目录
9.注意:该依赖目前不支持java自训练模型,自训练接口仅对c++语言提供,社区补充版本的依赖可以支持模型自训练
先一步一步来,中间会讲解会踩到的坑。
作者环境:java11(最好用java8)
1.正常用maven导入坐标:
<dependency>
<groupId>org.openpnp</groupId>
<artifactId>opencv</artifactId>
<version>4.5.3-1</version>
</dependency>
依赖下载完别急着写代码
你急着把测试代码写了会遇到:
库文件找不到异常
2.下载库文件:
Releases - OpenCVhttps://opencv.org/releases/
下载对应版本
下载好运行解压到指定目录后一路打开找到这个opencv_java453.dll
3.下载模型文件:
这个是用于人脸识别的模型
4.把库文件粘贴到你的jdk的bin目录下
因为你在javase的测试main方法调用opencv的api,该api底层是会依赖opencv_java453.dll这个库的,jvm首先就在bin目录下查找该库,所以需要把库文件放bin下。
5.把模型文件放到你的项目目录
可以是根目录也可以像作者一样放src下:
6.编写你的javase测试代码
注意图片文件路径、模型文件路径,不要无脑copy过来直接运行,你只需要修改成你自己项目里面的路径就可以了
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import java.util.Arrays;
import java.util.Base64;
/**
* @author mijiupro
*/
public class FaceDetection {
//人脸检测器
private static final CascadeClassifier FACE_DETECTOR;
//人脸模型xml文件路径
private static final String FACE_MODEL_PATH = "src/main/java/com/mi9688/common/opencv/model/haarcascade_frontalface_alt.xml";
//测试图片文件夹路径
private static final String TRAINING_DATA_DIR = "src/main/java/com/mi9688/common/opencv/sample";
//检测并处理后保存图片路径
private static final String DETECTION_RESULT ="src/main/java/com/mi9688/common/opencv/result/result.jpg";
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);//加载库文件
FACE_DETECTOR = new CascadeClassifier(FACE_MODEL_PATH);//创建级联分类器加载人脸模型xml文件
}
/**
* 测试模型
*/
public static void testModel() {
// 加载样本图片
Mat image = Imgcodecs.imread(TRAINING_DATA_DIR+"/1.jpg");
// 检测人脸
MatOfRect faceDetections = new MatOfRect();
FACE_DETECTOR.detectMultiScale(image, faceDetections);
int numFaces = faceDetections.toArray().length;
System.out.println("人脸数量: " + numFaces);
// 绘制标人脸识框并打印人脸位置坐标
Arrays.stream(faceDetections.toArray()).forEach(
(rect) -> {
Imgproc.rectangle(image, new Point(rect.x, rect.y),
new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0));
System.out.println("坐标: (" + rect.x + ", " + rect.y + ")");
});
// 保存处理后的图片
Imgcodecs.imwrite(DETECTION_RESULT, image);
}
public static void main(String[] args) {
testModel();
}
}
运行后你会得到:
恭喜你完成了第一步,当你把人脸识别封装成接口时,又会遇到惊喜,下面说一下这个惊喜。
7.编写前端提交人脸图片的后端人脸校验接口
继续在该测试类写个人脸校验静态方法
public static Boolean hasOneFace(String base64Image) {
try {
Mat imageMat = Imgcodecs.imdecode(new MatOfByte(Base64.getDecoder().decode(base64Image)), Imgcodecs.IMREAD_UNCHANGED);
// 转换为灰度图像
Mat grayImageMat = new Mat();
Imgproc.cvtColor(imageMat, grayImageMat, Imgproc.COLOR_BGR2GRAY);
// 检测人脸
MatOfRect faceDetections = new MatOfRect();
FACE_DETECTOR.detectMultiScale(grayImageMat, faceDetections, 1.1, 2, 0, new Size(30, 30));
int numFaces = faceDetections.toArray().length;
log.info("人脸数量: " + numFaces);
if (numFaces != 1) {
log.info("请确保人脸数量为1,且人脸位于图片正中央");
return false;
}
Arrays.stream(faceDetections.toArray()).forEach(rect -> log.info("坐标: (" + rect.x + ", " + rect.y + ")"));
} catch (Exception e) {
log.info(e.getMessage());
}
return true;
}
controller:
@PostMapping("/staff-is-face1")
public Result<?> isFaceByOpencv(@RequestBody String faceBase64) {
if(FaceDetection.hasOneFace(faceBase64)){
return Result.success();
}
return Result.error(ResultCode.FAIL);
}
8惊喜:这时前端调用你的接口就会:
又出现库找不到异常了:
这时候你大概率引入了热部署依赖大部分都是这个原因:
这时你需要注释掉热部署导入,然后maven刷新依赖,重启就解决了。
如果还没有解决
那就在你的C:\Windows\System32目录也复制一份库文件opencv_java453.dll
ok到这里你99%已经可以愉快使用你的opencv了
9.注意:该依赖目前不支持java自训练模型,自训练接口仅对c++语言提供,社区补充版本的依赖可以支持模型自训练
地址如下:https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml
maven坐标:
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.9</version>
</dependency>
具体看github官方文档