出现问题
使用SpringBoot整合OpenCV,初始化class/调用
java.lang.UnsatisfiedLinkError: org.opencv.objdetect.CascadeClassifier.CascadeClassifier_0(Ljava/lang/String;)J
快速解决
-
如果你使用了
SpringBoot,请去掉spring-boot-devtools这个依赖项 -
如果你没有引入dll文件。请采用如下三种方式之一引入dll
dll引入的方式
这里的dll是opencv的动态链接库,下载地址
方法一:动态引入(推荐)
-
在resource下新建lib/opencv
-
放入
opencv_javaxxx.dll,xxx取决于你的jar版本,如opencv_java455.dll -
静态初始化区使用如下代码
URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java455.dll"); System.load(url.getPath());
方法二:放入system32或者jre/bin目录
-
将dll放入system32或者jre/bin目录
-
静态初始化区使用如下代码加载,其中Core是
org.opencv.core.CoreSystem.loadLibrary(Core.NATIVE_LIBRARY_NAME);
方法三:指定 java.library.path
-
将dll放入任意位置,如文件夹
F:\opencv_java\x64 -
使用
-Djava.library.path参数启动SpringBoot(jar)项目java -Djava.library.path=F:\opencv_java\x64 -jar xxx -
(或者)如果你使用IDEA,请点如下图标注1的位置,点击【Edit Configurations..】,再在标注2处加入参数

-
静态初始化区使用如下代码加载,其中Core是
org.opencv.core.CoreSystem.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.load(param)和System.loadLibrary(param)的区别
load传入dll文件的绝对路径,可以是任意路径,表示加载路径为这个参数的dll
loadLibrary,传入这个dll文件的名字(不含路径和后缀),表示从环境变量中读取改名字的dll文件。
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);中的Core.NATIVE_LIBRARY_NAME实际上是随着这个jar包写死的,如opencv-455.jar就是会返回opencv_455这个名字。
IDEA:SpringBoot与OpenCV整合完整过程
完成一次人脸特征识别的过程
导入jar包
-
下载jar包,下载地址
-
依次点击File->Project Struture->Libraries->加号->Java,选择你的jar包路径,导入成功后可以看到最下方已经有了jar包

加载动态链接库(dll)
使用的是上方方法一,这里演示了,你可以选择任意方式
创建人脸识别器
- 存放级联分类器xml文件,文件在
OpenCV/data/haarcascades
不同的级联分类器的区别可以参考:OpenCV中4个人脸级联分类器_LinJM-机器视觉的博客-CSDN博客
-
加载xml文件
CascadeClassifier faceDetector = new CascadeClassifier("F:\\Project\\examDemo\\examDemo\\src\\main\\resources\\lib\\opencv\\haarcascade_frontalface_alt.xml");此处必须使用绝对路径,不能存放在jar包内,并且动态获取Jar包内的Resource下的的路径。猜测是JNI调用时需要一个能访问的xml文件路径,而不是Jar包内的文件。
识别
Mat faceImag = imread("F:\\Project\\examDemo\\examDemo\\src\\main\\resources\\images\\image.png");
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(faceImag,faceDetections);
Rect[] rects = faceDetections.toArray();
全部代码
// 解决awt报错问题
System.setProperty("java.awt.headless", "false");
System.out.println(System.getProperty("java.library.path"));
// 加载动态库
URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java455.dll");
System.load(url.getPath());
Mat faceImag = imread("F:\\Project\\examDemo\\examDemo\\src\\main\\resources\\images\\image.png");
// 人脸识别器
CascadeClassifier faceDetector = new CascadeClassifier("F:\\Project\\examDemo\\examDemo\\src\\main\\resources\\lib\\opencv\\haarcascade_frontalface_alt.xml");
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(faceImag,faceDetections);
Rect[] rects = faceDetections.toArray();
if(rects != null && rects.length >= 1){
for (Rect rect : rects) {
Imgproc.rectangle(faceImag,rect,Scalar.all(1));
}
}
imshow("人脸检测图片",faceImag);
waitKey();
效果
会全出人脸的位置。如下图:
