如何在 Windows 上的 Java 中使用 OpenCV 4.4.0(带有 contrib 模块)?
How to use OpenCV 4.4.0 (with contrib modules) in Java on Windows?
我已经在 Windows 64 位上从源代码编译了 OpenCV 4.4.0 以及 java 绑定,我正在尝试编译一个基本测试,但是我 运行遇到意外错误。
以下是我设置 eclipse 项目的方法:
以及 jar 引用本机库的方式:
这是基本测试片段:
import org.opencv.core.*;
public class CVTest {
public static void main(String[] args) {
System.load(Core.NATIVE_LIBRARY_NAME);
}
}
抛出这个异常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: opencv_java440
at java.lang.Runtime.load0(Runtime.java:806)
at java.lang.System.load(System.java:1086)
at CVTest.main(CVTest.java:8)
我已经尝试硬编码绝对路径作为测试:
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll");
但是我 运行 进入这个异常:
线程“main”中的异常java.lang.UnsatisfiedLinkError:
C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1817)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at CVTest.main(CVTest.java:9)
我没想到会这样,因为我已经编译了 OpenCV 4 64 位,并且我运行正在 JVM 1.8 64 位上安装它。
我试过一次手动加载一个库并使用 Dependency Walker,最后设法实例化了一个 Mat
,如下所示:
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_core440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_imgproc440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_imgcodecs440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_img_hash440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_videoio_ffmpeg440_64.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_videoio440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_photo440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_xphoto440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_flann440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_features2d440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_calib3d440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_phase_unwrapping440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_structured_light440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_xfeatures2d440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_video440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_ximgproc440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_aruco440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_bgsegm440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_bioinspired440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_objdetect440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_face440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_dnn440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_tracking440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_plot440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_ml440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_text440.dll");
// f.finally load the JNI wrapper native lib
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll");
这行得通,但按顺序对每个 DLL 进行硬编码感觉就像是一个混乱的 hack。
还有其他人 运行 遇到这种情况吗?
在 Windows Java 中加载 OpenCV 4 库的优雅方式是什么?
为了方便测试,我上传了以下内容:
- opencv_440_windows32.zip:32 位 headers/dynamic 库(以及 java 包装器)
- opencv_440_windows64.zip:64 位 headers/dynamic 库(以及 java 包装器)
更新
这是静态库,包括 java 基于 José 出色回答的绑定:
请尝试设置 java.library.path
属性 以指示 JVM 在哪里可以找到本机库(我想你需要根据你的情况配置 C:/Users/george.profenza/Documents/eclipse/CVTest/lib\
)。
从命令行(或 Eclipse Run/Debug 配置),您可以包含所需的库,如下所示:
java -Djava.library.path=<path_to_dlls> <main class>
在Java代码中,你可以这样设置属性:
System.setProperty(“java.library.path”, “/path/to/dlls”);
除了修改 Run/Debug 配置以在 Eclipse 中包含 -Djava.library.path
之外,要在此 IDE 中设置 java.library.path
属性 您可以按照几个指南(例如 this)。基本上:
- 在
Package Explorer
中右键单击进入您的项目。
- Select
Build Path → Configure Build Path...
选项。
- 在出现的 window 中,select
Libraries
选项卡。
- 展开
JRE System library
选项,selectNative library location
。
- 单击右侧面板中的
Edit...
按钮。
- 找到所需的库,然后单击
OK
。
可能需要在没有共享库的情况下构建库,以避免 dll 依赖性问题。你可以看到一个深入的解释here。注意作者说的地方:
When OpenCV is built as a set of static libraries (-DBUILD_SHARED_LIBS=OFF
option) the Java bindings dynamic library is all-sufficient, i.e. doesn't depend on other OpenCV libs, but includes all the OpenCV code inside.
尝试 pre-compiled 库应该更容易。
<!-- https://mvnrepository.com/artifact/org.openpnp/opencv -->
<dependency>
<groupId>org.openpnp</groupId>
<artifactId>opencv</artifactId>
<version>4.3.0-2</version>
</dependency>
几年前我试过这个库,它有效。
我已经在 Windows 64 位上从源代码编译了 OpenCV 4.4.0 以及 java 绑定,我正在尝试编译一个基本测试,但是我 运行遇到意外错误。
以下是我设置 eclipse 项目的方法:
以及 jar 引用本机库的方式:
这是基本测试片段:
import org.opencv.core.*;
public class CVTest {
public static void main(String[] args) {
System.load(Core.NATIVE_LIBRARY_NAME);
}
}
抛出这个异常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: opencv_java440
at java.lang.Runtime.load0(Runtime.java:806)
at java.lang.System.load(System.java:1086)
at CVTest.main(CVTest.java:8)
我已经尝试硬编码绝对路径作为测试:
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll");
但是我 运行 进入这个异常:
线程“main”中的异常java.lang.UnsatisfiedLinkError:
C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1817)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at CVTest.main(CVTest.java:9)
我没想到会这样,因为我已经编译了 OpenCV 4 64 位,并且我运行正在 JVM 1.8 64 位上安装它。
我试过一次手动加载一个库并使用 Dependency Walker,最后设法实例化了一个 Mat
,如下所示:
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_core440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_imgproc440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_imgcodecs440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_img_hash440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_videoio_ffmpeg440_64.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_videoio440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_photo440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_xphoto440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_flann440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_features2d440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_calib3d440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_phase_unwrapping440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_structured_light440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_xfeatures2d440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_video440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_ximgproc440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_aruco440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_bgsegm440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_bioinspired440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_objdetect440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_face440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_dnn440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_tracking440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_plot440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_ml440.dll");
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_text440.dll");
// f.finally load the JNI wrapper native lib
System.load("C:\Users\george.profenza\Documents\eclipse\CVTest\lib\opencv_java440.dll");
这行得通,但按顺序对每个 DLL 进行硬编码感觉就像是一个混乱的 hack。 还有其他人 运行 遇到这种情况吗?
在 Windows Java 中加载 OpenCV 4 库的优雅方式是什么?
为了方便测试,我上传了以下内容:
- opencv_440_windows32.zip:32 位 headers/dynamic 库(以及 java 包装器)
- opencv_440_windows64.zip:64 位 headers/dynamic 库(以及 java 包装器)
更新
这是静态库,包括 java 基于 José 出色回答的绑定:
请尝试设置 java.library.path
属性 以指示 JVM 在哪里可以找到本机库(我想你需要根据你的情况配置 C:/Users/george.profenza/Documents/eclipse/CVTest/lib\
)。
从命令行(或 Eclipse Run/Debug 配置),您可以包含所需的库,如下所示:
java -Djava.library.path=<path_to_dlls> <main class>
在Java代码中,你可以这样设置属性:
System.setProperty(“java.library.path”, “/path/to/dlls”);
除了修改 Run/Debug 配置以在 Eclipse 中包含 -Djava.library.path
之外,要在此 IDE 中设置 java.library.path
属性 您可以按照几个指南(例如 this)。基本上:
- 在
Package Explorer
中右键单击进入您的项目。 - Select
Build Path → Configure Build Path...
选项。 - 在出现的 window 中,select
Libraries
选项卡。 - 展开
JRE System library
选项,selectNative library location
。 - 单击右侧面板中的
Edit...
按钮。 - 找到所需的库,然后单击
OK
。
可能需要在没有共享库的情况下构建库,以避免 dll 依赖性问题。你可以看到一个深入的解释here。注意作者说的地方:
When OpenCV is built as a set of static libraries (
-DBUILD_SHARED_LIBS=OFF
option) the Java bindings dynamic library is all-sufficient, i.e. doesn't depend on other OpenCV libs, but includes all the OpenCV code inside.
尝试 pre-compiled 库应该更容易。
<!-- https://mvnrepository.com/artifact/org.openpnp/opencv -->
<dependency>
<groupId>org.openpnp</groupId>
<artifactId>opencv</artifactId>
<version>4.3.0-2</version>
</dependency>
几年前我试过这个库,它有效。