Java + opencv 实现人脸识别、图片人脸识别、视频人脸识别、摄像头实时人脸识别
最编程
2024-03-30 22:44:45
...
大家好,又见面了,我是你们的朋友全栈君。
搭建环境
opencv官网下载windows安装包 https://opencv.org/releases/ 选择最新版4.1.1 下载完成后是一个opencv-4.1.1-vc14_vc15.exe,双击安装。
重要: 把安装路径D:\Sofeware\opencv\build\bin下面的两个文件复制到 D:\Sofeware\opencv\build\java\x64 (为了支持读取视频流)
集成到IDEA中
打开project structure –> modules –>dependencies 引入D:\Sofeware\opencv\build\java 下的opencv-411.jar包,然后编辑这个包加入D:\Sofeware\opencv\build\x64 路径里的资源
pom.xml 相关依赖包
<!-- 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>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.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>
创建FaceVideo.class 主方法类 来进行人脸识别测试
注意修改下面 faceDetector = new CascadeClassifier( 中.xml路径改成你的路径。
package com.jack.demo.face;
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
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 java.util.Arrays;
/** * * @Title: Opencv 图片人脸识别、实时摄像头人脸识别、视频文件人脸识别 * @Description: OpenCV-4.1.1 测试文件 * @date: 2019年8月19日 17:17:48 * @version: V-1.0.0 * */
public class FaceVideo {
// 初始化人脸探测器
static CascadeClassifier faceDetector;
static int i=0;
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
faceDetector = new CascadeClassifier("D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
}
public static void main(String[] args) {
// 1- 从摄像头实时人脸识别,识别成功保存图片到本地
getVideoFromCamera();
// 2- 从本地视频文件中识别人脸
// getVideoFromFile();
// 3- 本地图片人脸识别,识别成功并保存人脸图片到本地
face();
// 4- 比对本地2张图的人脸相似度 (越接近1越相似)
String basePicPath = "D:\\Documents\\Pictures\\";
double compareHist = compare_image(basePicPath + "fc.jpg", basePicPath + "fc_1.jpg");
System.out.println(compareHist);
if (compareHist > 0.72) {
System.out.println("人脸匹配");
} else {
System.out.println("人脸不匹配");
}
}
/** * OpenCV-4.1.1 从摄像头实时读取 * @return: void * @date: 2019年8月19日 17:20:13 */
public static void getVideoFromCamera() {
//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));
index=HighGui.waitKey(100);
if (index==27) {
capture.release();
break;
}
}
}else{
System.out.println("摄像头未开启");
}
try {
capture.release();
Thread.sleep(1000);
System.exit(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
/** * OpenCV-4.1.1 从视频文件中读取 * @return: void * @date: 2019年8月19日 17:20:20 */
public static void getVideoFromFile() {
VideoCapture capture=new VideoCapture();
capture.open("C:\\Users\\Administrator\\Desktop\\1.avi");//1 读取视频文件的路径
if(!capture.isOpened()){
System.out.println("读取视频文件失败!");
return;
}
Mat video=new Mat();
int index=0;
while(capture.isOpened()) {
capture.read(video);//2 视频文件的视频写入 Mat video 中
HighGui.imshow("本地视频识别人脸", getFace(video));//3 显示图像
index=HighGui.waitKey(100);//4 获取键盘输入
if(index==27) {
//5 如果是 Esc 则退出
capture.release();
return;
}
}
}
/** * OpenCV-4.1.1 人脸识别 * @date: 2019年8月19日 17:19:36 * @param image 待处理Mat图片(视频中的某一帧) * @return 处理后的图片 */
public static Mat getFace(Mat image) {
// 1 读取OpenCV自带的人脸识别特征XML文件(faceDetector)
// CascadeClassifier facebook=new CascadeClassifier("D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
// 2 特征匹配类
MatOfRect face = new MatOfRect();
// 3 特征匹配
faceDetector.detectMultiScale(image, face);
Rect[] rects=face.toArray();
System.out.println("匹配到 "+rects.length+" 个人脸");
if(rects != null && rects.length >= 1) {
// 4 为每张识别到的人脸画一个圈
for (int i = 0; i < rects.length; i++) {
Imgproc.rectangle(image, new Point(rects[i].x, rects[i].y), new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height), new Scalar(0, 255, 0));
Imgproc.putText(image, "Human", new Point(rects[i].x, rects[i].y), Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, 1.0, new Scalar(0, 255, 0), 1, Imgproc.LINE_AA, false);
//Mat dst=image.clone();
//Imgproc.resize(image, image, new Size(300,300));
}
i++;
if(i==3) {
// 获取匹配成功第10次的照片
Imgcodecs.imwrite("D:\\Documents\\Pictures\\" + "face.png", image);
}
}
return image;
}
/** * OpenCV-4.1.1 图片人脸识别 * @return: void * @date: 2019年5月7日12:16:55 */
public static void face() {
// 1 读取OpenCV自带的人脸识别特征XML文件
//OpenCV 图像识别库一般位于 opencv\sources\data 下面
// CascadeClassifier facebook=new CascadeClassifier("D:\\Sofeware\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
// 2 读取测试图片
String imgPath = "D:\\Documents\\Pictures\\he.png";
Mat image=Imgcodecs.imread(imgPath);
if(image.empty()){
System.out.println("image 内容不存在!");
return;
}
// 3 特征匹配
MatOfRect face = new MatOfRect();
faceDetector.detectMultiScale(image, face);
// 4 匹配 Rect 矩阵 数组
Rect[] rects=face.toArray();
System.out.println("匹配到 "+rects.length+" 个人脸");
// 5 为每张识别到的人脸画一个圈
int i =1 ;
for (Rect rect : face.toArray()) {
Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
new Scalar(0, 255, 0), 3);
imageCut(imgPath, "D:\\Documents\\Pictures\\"+i+".jpg", rect.x, rect.y, rect.width, rect.height);// 进行图片裁剪
i++;
}
// 6 展示图片
HighGui.imshow("人脸识别", image);
HighGui.waitKey(0);
}
/** * 裁剪人脸 * @param imagePath * @param outFile * @param posX * @param posY * @param width * @param height */
public static void imageCut(String imagePath, String outFile, int posX, int posY, int width, int height) {
// 原始图像
Mat image = Imgcodecs.imread(imagePath);
// 截取的区域:参数,坐标X,坐标Y,截图宽度,截图长度
Rect rect = new Rect(posX, posY, width, height);
// 两句效果一样
Mat sub = image.submat(rect); // Mat sub = new Mat(image,rect);
Mat mat = new Mat();
Size size = new Size(width, height);
Imgproc.resize(sub, mat, size);// 将人脸进行截图并保存
Imgcodecs.imwrite(outFile, mat);
System.out.println(String.format("图片裁切成功,裁切后图片文件为: %s", outFile));
}
/** * 人脸比对 * @param img_1 * @param img_2 * @return */
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(1000);
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;
}
/** * 灰度化人脸 * @param img * @return */
public static Mat conv_Mat(String img) {
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()) {
Mat face = new Mat(image1, rect);
return face;
}
return null;
}
/** * OpenCV-4.1.1 将摄像头拍摄的视频写入本地 * @return: void * @date: 2019年8月19日 17:20:48 */
public static void writeVideo() {
//1 如果要从摄像头获取视频 则要在 VideoCapture 的构造方法写 0
VideoCapture capture=new VideoCapture(0);
Mat video=new Mat();
int index=0;
Size size=new Size(capture.get(Videoio.CAP_PROP_FRAME_WIDTH),capture.get(Videoio.CAP_PROP_FRAME_HEIGHT));
VideoWriter writer=new VideoWriter("D:/a.mp4",VideoWriter.fourcc('D', 'I', 'V', 'X'), 15.0,size, true);
while(capture.isOpened()) {
capture.read(video);//2 将摄像头的视频写入 Mat video 中
writer.write(video);
HighGui.imshow("像头获取视频", video);//3 显示图像
index=HighGui.waitKey(100);//4 获取键盘输入
if(index==27) {
//5 如果是 Esc 则退出
capture.release();
writer.release();
return;
}
}
}
}
开始测试>>>
右键执行FaceVideo.Class Main()方法
如果出现运行Main方法时报错:java.lang.UnsatisfiedLinkError: no opencv_java411 in java.library.path
(需要加一个运行参数)
编辑启动类:Edit Configuration VM options:-Djava.library.path=D:\Sofeware\opencv\build\java\x64;
1- 测试摄像头实时识别人脸:
2- 测试本地视频识别人脸
3- 测试本地图片人脸识别
4- 测试本地2张图片人脸的相似度
完结。
推荐阅读
-
人脸识别+python-opencv 实现摄像头实时人脸识别
-
微信 "扫一扫 "物联网,全面揭秘 "扫一扫 "背后的扫盲技术!-1.1 扫一扫感知物体是做什么的? 1.1 微信扫一扫是做什么的? 扫一扫识物是指以图片或视频(商品图片:鞋/包/美妆/服饰/家电/玩具/图书/食品/珠宝/家具/其他商品)为输入媒介,挖掘微信内容生态中的有价值信息(电商+百科+资讯,如图1所示),并展示给用户。这里的电商基本涵盖了微信小程序覆盖上亿SKU的全量优质电商,可以支持用户货比N家并直接下单购买,百科和资讯则聚合了微信内的头部自媒体如搜狗、搜搜、百度等,向用户展示和分享拍摄商品相关的内容资讯。 图 1 扫一扫识别功能示意图 欢迎大家更新iOS新版微信→扫一扫→识货,亲自体验,也欢迎大家通过识货界面的反馈按钮向我们提交反馈意见。 扫一扫识物实景图展示 1.2 扫一扫识物有哪些使用场景? 扫一扫识物的目的是为用户访问微信内部生态内容开辟一个新窗口,以用户扫图片为输入形式,为用户提供微信生态内容中的百科、资讯、电商等作为展示页面。除了用户熟悉的扫一扫操作外,我们还将进一步拓展长按操作,让用户更方便地进行扫一扫操作。"扫一扫知事 "的落地场景主要涵盖三大部分: a. 科普知识: a.科普知识。用户通过扫一扫,可以在微信生态圈中获取该对象的百科、资讯等常识或趣闻,帮助用户更好地了解该对象; b.购物场景。同样的搜索功能支持用户看到喜欢的商品立即检索到微信小程序电商中的同款商品,支持用户即扫即购; c.广告场景。扫一扫识别物体可以辅助公众号文章、视频更好地理解其中蕴含的图片信息,从而更好地投放匹配广告,提高点击率。 1.3 Sweep Sense 为 Sweep 家族带来了哪些新技术? 对于扫一扫来说,大家耳熟能详的应该就是扫一扫二维码、扫一扫小程序码、扫一扫条形码、扫一扫翻译了。无论是各种形式的编码还是文字字符,都可以看作是图片的一种特定编码形式,而物的识别则是对自然场景图片的识别,这对于扫一扫家族来说是一个质的飞跃,我们希望从物的识别入手,进一步拓展扫一扫对自然场景图片的理解能力,比如扫酒、扫车、扫植物、扫人脸等服务,如下图3所示。 图 3 Sweep 家族
-
腾讯电子认证实现人脸识别 (.Net6)
-
微信公众号--小程序实现人脸核身(人脸识别)
-
基于 Python 的 OpenCV 视觉图像处理 OpenCV 简单人脸检测/识别 实用案例二 简单人脸检测 添加眼镜效果
-
人工智能的 Java AI 实现--我在 Github 上找到了--基于 Java 的计算机视觉人脸识别 Java 实现(开源代码--(人脸识别--自动驾驶--汽车跟踪--手写数字识别器))带你导入代码并测试使用--四、测试运行
-
基于 Python 的 OpenCV 视觉图像处理 OpenCV 简单人脸检测/识别案例之十二 简单人脸识别
-
从头开始玩人脸识别的 RGB 人脸实时检测
-
从头开始玩人脸识别的 RGB 人脸实时检测 2
-
明星专家系统的 Python 实现:自动人脸识别比较