Java programming, opencv unsatisfied link error

2020-04-21 01:54发布

问题:

OpenCV libraries gives unsatisfied link error in capturing a video stream.

Where should be the opencv 3.2.0 libraries? What is the correct path for packages of opencv classes?

Code where to generate this error:

package opencv;

import org.opencv.core.*; 

import org.opencv.imgcodecs.Imgcodecs;        
import org.opencv.videoio.VideoCapture;     
public class VideoCap 
{

    public static void main (String args[]){

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // error

        VideoCapture camera = new VideoCapture(0);

        if(!camera.isOpened()){
            System.out.println("Error");
        }
    else {
            Mat frame = new Mat();
            while(true){
                if (camera.read(frame)){
                    System.out.println("Frame Obtained");
                    System.out.println("Captured Frame Width " + 
                    frame.width() + " Height " + frame.height());
                    Imgcodecs.imwrite("camera.jpg", frame);
                    System.out.println("OK");
                    break;
                }
            }   
        }
        camera.release();
    }
}

The exception is:

Exception in thread "main" java.lang.UnsatisfiedLinkError:
    no opencv_java320 in java.library.path
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at opencv.VideoCap.main(VideoCap.java:9)

回答1:

Try to clone the repository below:

https://github.com/hellonico/opencv4_java_tutorial.git

Add your class in the java folder, and instead of using System.loadLibrary ... use:

NativeLoader.loadLibrary(Core.NATIVE_LIBRARY_NAME);

This will load a properly compiled version of OpenCV to run within the JVM.



回答2:

The following picture is my contents of a directory in which opencv 4.0.1 installed with a tesseract library. I built it with a mingw32 gcc compiler on a windows actually 10.

I think you have at least two file opencv_javaXXX_dll and opencv-XXX.jar.

I have built the opencv library with mingw32 gcc compiler on Windows 10 So, i must set the bin directory where mingw32 installed and java.

I set the variables on a cmd window,

SET MINGW_HOME=D:/DEV/SDK/msys32/mingw32
SET JAVA_HOME=D:/DEV/SDK/JDK/jdk1.8.0_152
SET PATH=%MINGW_HOME%/bin;%JAVA_HOME%/bin

Here are my test commands.

C:\Windows\System32\cmd.exe /C "javac -cp .;opencv-410.jar -d . *.java & java -Djava.library.path=. -cp .;opencv-410.jar VideoCap"

There are three possible cases.

1. Can't find dependent libraries problem.

This problem indicates that you have some libraries missing.

In this case, I should get this message if i don't have a libtesseract40.dll in the same directory or system's path.

2. An unsatisfied link error with a library name.

This commonly occurred when a name of library mismatched. I will get the error if i have a libopencv_java410.dll as a library name.

3. An unsatisfied link error with a method name.

If you have still got another unsatisfied link - method name.

For example,

java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_eye(III)J

I think this will be complicate problem.

You might have your library compile and build from the scratch.

On a windows os, I had to add a build flag at following line in a CMakefile.txt.

I added a '--add-stdcall-alias' flag.

A location of a CMakefile.txt:

[~opencv-4.1.0 source directory]\modules\java\jni\CMakefile.txt

  elseif(((CV_GCC OR CV_CLANG OR UNIX) OR (OPENCV_FORCE_FAT_JAVA_LIB_LD_RULES)) AND (NOT OPENCV_SKIP_FAT_JAVA_LIB_LD_RULES))
    ocv_target_link_libraries(${the_module} LINK_PRIVATE -Wl,-whole-archive ${__deps} -Wl,-no-whole-archive -Wl,--add-stdcall-alias)

The complete test code is as following:

//A test code for the opencv 4.0.1 
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;

public class HelloCV {

    public static void test1(){
       System.load(new java.io.File(".").getAbsolutePath() + java.io.File.separator + "opencv_java410.dll");

        VideoCapture camera = new VideoCapture(0);


        if(!camera.isOpened()){
            System.out.println("Error");
        }
        else {
            Mat frame = new Mat();
            while(true){
                if (camera.read(frame)){
                    System.out.println("Frame Obtained");
                    System.out.println("Captured Frame Width " + 
                    frame.width() + " Height " + frame.height());
                    Imgcodecs.imwrite("camera.jpg", frame);
                    System.out.println("OK");
                    break;
                }
            }   
        }
        camera.release();
    }

    public static void test2(){
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // error

        VideoCapture camera = new VideoCapture(0);


        if(!camera.isOpened()){
            System.out.println("Error");
        }
        else {
            Mat frame = new Mat();
            while(true){
                if (camera.read(frame)){
                    System.out.println("Frame Obtained");
                    System.out.println("Captured Frame Width " + 
                    frame.width() + " Height " + frame.height());
                    Imgcodecs.imwrite("camera.jpg", frame);
                    System.out.println("OK");
                    break;
                }
            }   
        }
        camera.release();
    }   

    public static void main (String args[]){
        test1();
        test2();
    }
}