先一步一步来,中间会讲解会踩到的坑。
作者环境:java11(最好用java8)
org.openpnp
opencv
4.5.3-1
依赖下载完别急着写代码
你急着把测试代码写了会遇到:
库文件找不到异常
Releases - OpenCVhttps://opencv.org/releases/
下载对应版本
下载好运行解压到指定目录后一路打开找到这个opencv_java453.dll
https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xmlhttps://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml
这个是用于人脸识别的模型
因为你在javase的测试main方法调用opencv的api,该api底层是会依赖opencv_java453.dll这个库的,jvm首先就在bin目录下查找该库,所以需要把库文件放bin下;
可以是根目录也可以像作者一样放src下:
注意图片文件路径、模型文件路径,不要无脑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();
}
}
运行后你会得到:
恭喜你完成了第一步,当你把人脸识别封装成接口时,又会遇到惊喜,下面说一下这个惊喜。
继续在该测试类写个人脸校验静态方法
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);
}
又出现库找不到异常了:
这时候你大概率引入了热部署依赖大部分都是这个原因:
这时你需要注释掉热部署导入,然后maven刷新依赖,重启就解决了。
啥还没解决?
那就在你的C:\Windows\System32目录也复制一份库文件opencv_java453.dll
ok到这里你99%已经可以愉快使用你的opencv了
地址如下:https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_alt.xml
maven坐标:
org.bytedeco
javacv-platform
1.5.9
具体看github官方文档