这篇文章主要介绍了java+opencv如何实现人脸识别功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
Java的特点有哪些
Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。2.Java具有简单性、面向对象、分布式、安全性、平台独立与可移植性、动态性等特点。3.使用Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
背景:最近需要用到人脸识别,但又不花钱使用现有的第三方人脸识别接口,为此使用opencv结合java进行人脸识别(ps:opencv是开源的,使用它来做人脸识别存在一定的误差,效果一般)。
安装opencv
官网地址:https://opencv.org/ , 由于官网下载速度是真的慢
百度网盘:
链接: https://pan.baidu.com/s/1RpsP-I7v8pP2dkqALDw7FQ
提取码: pq7v
如果是官网下载,就无脑安装就行了,安装完毕后。
将图一的两个文件复制到图二中。
从我网盘下载的,忽略这些。
在项目中引入pom依赖
<!-- opencv + javacv + ffmpeg--> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>ffmpeg</artifactId> <version>4.1-1.4.4</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.4.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg-platform --> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>ffmpeg-platform</artifactId> <version>4.1-1.4.4</version> </dependency> <!-- 视频摄像头 --> <!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.4.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/opencv-platform --> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv-platform</artifactId> <version>4.0.1-1.4.4</version> </dependency>
导入库依赖
File --> Project Structure,点击Modules,选择需要使用opencv.jar的项目。
选择直接opencv安装路径
java代码demo
package org.Litluecat.utils;import org.apache.commons.lang.StringUtils;import org.opencv.core.*;import org.opencv.highgui.HighGui;import org.opencv.highgui.ImageWindow;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;import org.opencv.objdetect.CascadeClassifier;import org.opencv.videoio.VideoCapture;import org.opencv.videoio.VideoWriter;import org.opencv.videoio.Videoio;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.Arrays;public class FaceVideo { private static final Logger log = LoggerFactory.getLogger(FaceVideo.class); private static final String endImgUrl = "C:\\Users\\lenovo\\Desktop\\"; private static final String faceDetectorXML2URL = "D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml"; private static final String eyeDetectorXML2URL = "D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml"; private static int Matching_Accuracy = 100000; private static CascadeClassifier faceDetector; private static CascadeClassifier eyeDetector; private static int i=0; static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); faceDetector = new CascadeClassifier(faceDetectorXML2URL); eyeDetector = new CascadeClassifier(eyeDetectorXML2URL); } public static void main(String[] args) { log.info("开始人脸匹配"); long begin = System.currentTimeMillis(); // 1- 从摄像头实时人脸识别,识别成功保存图片到本地 try{ getVideoFromCamera(endImgUrl + "2.jpg"); //仅用于强制抛异常,从而关闭GUI界面 Thread.sleep(1000); int err = 1/0; // 2- 比对本地2张图的人脸相似度 (越接近1越相似)// double compareHist = FaceVideo.compare_image(endImgUrl + "test1.jpg" , endImgUrl + "face.jpg");// log.info("匹配度:{}",compareHist);// if (compareHist > 0.72) {// log.info("人脸匹配");// } else {// log.info("人脸不匹配");// } }catch (Exception e){ log.info("开始强制关闭"); log.info("人脸匹配结束,总耗时:{}ms",(System.currentTimeMillis()-begin)); System.exit(0); } } public static void getVideoFromCamera(String targetImgUrl) { //1 如果要从摄像头获取视频 则要在 VideoCapture 的构造方法写 0 VideoCapture capture = new VideoCapture(0); Mat video = new Mat(); int index = 0; if (capture.isOpened()) { while(i<3) { // 匹配成功3次退出 capture.read(video); HighGui.imshow("实时人脸识别", getFace(video, targetImgUrl)); //窗口延迟等待100ms,返回退出按键 index = HighGui.waitKey(100); //当退出按键为Esc时,退出窗口 if (index == 27) { break; } } }else{ log.info("摄像头未开启"); } //该窗口销毁不生效,该方法存在问题 HighGui.destroyAllWindows(); capture.release(); return; } public static Mat getFace(Mat image, String targetImgUrl) { MatOfRect face = new MatOfRect(); faceDetector.detectMultiScale(image, face); Rect[] rects=face.toArray(); log.info("匹配到 "+rects.length+" 个人脸"); if(rects != null && rects.length >= 1) { i++; if(i==3) { // 获取匹配成功第3次的照片 Imgcodecs.imwrite(endImgUrl + "face.jpg", image); FaceVideoThread faceVideoThread = new FaceVideoThread(targetImgUrl , endImgUrl + "face.jpg"); new Thread(faceVideoThread,"人脸比对线程").start(); } } return image; } public static String face2Img(String img) { String faceImg = null; Mat image0 = Imgcodecs.imread(img); Mat image1 = new Mat(); // 灰度化 Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY); // 探测人脸 MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(image1, faceDetections); // rect中人脸图片的范围 for (Rect rect : faceDetections.toArray()) { faceImg = img+"_.jpg"; // 进行图片裁剪 imageCut(img, faceImg, rect.x, rect.y, rect.width, rect.height); } if(null == faceImg){ log.info("face2Img未识别出该图像中的人脸,img={}",img); } return faceImg; } public static double compare_image(String img_1, String img_2) { Mat mat_1 = conv_Mat(img_1); Mat mat_2 = conv_Mat(img_2); Mat hist_1 = new Mat(); Mat hist_2 = new Mat(); //颜色范围 MatOfFloat ranges = new MatOfFloat(0f, 256f); //直方图大小, 越大匹配越精确 (越慢) MatOfInt histSize = new MatOfInt(Matching_Accuracy); Imgproc.calcHist(Arrays.asList(mat_1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges); Imgproc.calcHist(Arrays.asList(mat_2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges); // CORREL 相关系数 double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL); return res; } public static Mat conv_Mat(String img) { if(StringUtils.isBlank(img)){ return null; } Mat image0 = Imgcodecs.imread(img); Mat image1 = new Mat(); //Mat image2 = new Mat(); // 灰度化 Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY); //直方均匀 //Imgproc.equalizeHist(image1, image2); // 探测人脸 MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(image1, faceDetections); //探测人眼// MatOfRect eyeDetections = new MatOfRect();// eyeDetector.detectMultiScale(image1, eyeDetections); // rect中人脸图片的范围 Mat face = null; for (Rect rect : faceDetections.toArray()) { //给图片上画框框 参数1是图片 参数2是矩形 参数3是颜色 参数四是画出来的线条大小 //Imgproc.rectangle(image0,rect,new Scalar(0,0,255),2); //输出图片 //Imgcodecs.imwrite(img+"_.jpg",image0); face = new Mat(image1, rect); } if(null == face){ log.info("conv_Mat未识别出该图像中的人脸,img={}",img); } return face; }}
这边的人脸识别是另外其线程进行比对,代码如下。
package org.Litluecat.utils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class FaceVideoThread implements Runnable{ private static final Logger log = LoggerFactory.getLogger(FaceVideoThread.class); private String oneImgUrl = null; private String otherImgUrl = null; public FaceVideoThread(String oneImgUrl, String otherImgUrl){ this.oneImgUrl = oneImgUrl; this.otherImgUrl = otherImgUrl; } @Override public void run() { try { double compareHist = FaceVideo.compare_image(oneImgUrl , otherImgUrl); log.info("匹配度:{}",compareHist); if (compareHist > 0.72) { log.info("人脸匹配"); } else { log.info("人脸不匹配"); } } catch (Exception e) { e.printStackTrace(); } }}
提醒:如果运行异常,请添加你opencv的安装地址-Djava.library.path=D:\Sofeware\opencv\build\java\x64;
感谢你能够认真阅读完这篇文章,希望小编分享的“java+opencv如何实现人脸识别功能”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!