Search code examples
javaopencvjavacvdeeplearning4jdl4j

Is there a way to set up dependency for javacv's native part in maven, without manual installation and setting up java.library.path?


I have dependencies on org.bytedeco:opencv:4.1.2-1.5.2 that is in turn added to the project by

        <groupId>org.datavec</groupId>
        <artifactId>datavec-data-image</artifactId>
        <version>${datavec.version}</version>

And for the needs of datavec-data-image the open-cv is loaded well and all the internal open-cv actions are executed.

Then, I'd like to do some open cv executions explicitly. I use a class from https://github.com/rostrovsky/pdf-table that does this stuff:

public class PdfTableReader {

    private TableExtractor extractor;
    private PdfTableSettings settings;

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

and it fails with

Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java412 in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at pdftable.PdfTableReader.<clinit>(PdfTableReader.java:32)
    at pdftable.ExtractSyzlekFromPdf.main(ExtractSyzlekFromPdf.java:12)

What I should to do to make this explicit javacv part to work with datavec image code without doing the double explicit open-cv installation to some location on my pc and setting up the java.library.path explicitly? At least the datavec image code obtains it somehow without this explicit set up.

I also tried to follow up this answer: https://stackoverflow.com/a/57515132/1759063 but with no success (if I understand right, they use the dependency that ships native libs in a cross-platform way, i.e. ships all platform binaries and the needed one is used on the right platform). I suppose there should be a way to make java.library.path to be dynamically updated if the open-cv native binaries packed to the maven dependencies are attached to the project. But how?

If DL4J guys can explain how to use the javacv part there correctly, that would be perfect.


Solution

  • The Java API of OpenCV found in the org.opencv package doesn't come with a loader, so the libraries need to be loaded by something else externally. In the case of the JavaCPP Presets for OpenCV, the libraries and wrappers are all bundled in JAR files and we can call Loader.load(opencv_java.class) to load everything as documented here:
    https://github.com/bytedeco/javacpp-presets/tree/master/opencv#documentation

    JavaCV, Deeplearning4j, and DataVec do not use that Java API of OpenCV, they use the API found in the org.bytedeco.opencv package, which loads everything automatically, so they do not need to call anything.