face-detection:Java中用OpenCV实现人脸识别
java实现opencv人脸识别(二)
Java使用Opencv进行人脸识别
java调用本地摄像头,实现人脸识别‘
java引用虹软免费人脸识别sdk(demo)
opencv官网
OpenCV 教程
最近负责face服务,有关于人脸检测,比对和识别等功能的维护。一直用的是虹软第三方的sdk,查了下资料发现网友说opencv可以实现该功能。
OpenCV是一个用于图像处理、分析、机器视觉方面的开源函数库。
无论你是做科学研究,还是商业应用,opencv都可以作为你理想的工具库,因为,对于这两者,它完全是免费的。
该库采用C及C++语言编写,可以在windows, linux, mac OSX系统上面运行。该库的所有代码都经过优化,计算效率很高,因为,它更专注于设计成为一种用于实时系统的开源库。opencv采用C语言进行优化,而且,在多核机器上面,其运行速度会更快。它的一个目标是提供友好的机器视觉接口函数,从而使得复杂的机器视觉产品可以加速面世。该库包含了横跨工业产品检测、医学图像处理、安防、用户界面、摄像头标定、三维成像、机器视觉等领域的超过500个接口函数。
opencv
文件夹,进入到 build/java
目录下x64
文件夹中的 opencv_java3410.dll
文件拷贝到本机设置的 %JAVA_HOME%\bin
目录下(我这里用的是 3.4.10 版本)站在巨人的肩膀上:https://github.com/lyk2655/face-detection.git
在 idea 中导入 opencv\opencv\build\java
中的 jar 包
文件目录结构
# 防丢失
│ opencv-demo.iml
│ pom.xml
│
├─src
│ ├─main
│ │ ├─java
│ │ │ └─org
│ │ │ └─developer #具体代码的存放位置
│ │ │ FaceDetector.java
│ │ │
│ │ └─resources #src下主要存放人脸的图片
│ │ │ haarcascade_frontalface_alt.xml # opencv 的人脸分类器
│ │ │
│ │ ├─dst
│ │ │ 1.txt
│ │ │
│ │ └─src
│ │ 1001.JPG
│ │ 1002.JPG
│ │ 1003.JPG
│ │ 19.jpg
│ │ 20.jpg
│ │ 21.jpg
│ │ 22.jpg
│ │ 23.jpg
│ │ 24.jpg
│ │ 26.jpg
│ │ 27.jpg
│ │ 28.jpg
│ │ 31.jpg
│ │ 32.jpg
│ │ 33.jpg
│ │ 35.jpg
│ │ 36.jpg
│ │ five.jpg
│ │ group.jpg
│ │ many.JPG
│ │ ntest1.PNG
│ │ shekhar.JPG
│ │ timg.jpg
│ │ xiyou.JPG
│ │ zhuyin.JPG
│ │ zy.JPG
│ │
│ └─test
│ └─java
│ └─org
│ └─developer
│ FaceDetectorTest.java
│
└─target
├─classes
│ │ dst20200924155637.png
│ │ dst202009241556370.png
│ │ dst20200924155858.png
│ │ dst202009241558580.png
│ │ dst202009241558581.png
│ │ dst2020092415585810.png
│ │ dst2020092415585811.png
│ │ dst2020092415585812.png
│ │ dst2020092415585813.png
│ │ dst2020092415585814.png
│ │ dst2020092415585815.png
│ │ dst2020092415585816.png
│ │ dst2020092415585817.png
│ │ dst2020092415585818.png
│ │ dst202009241558582.png
│ │ dst202009241558583.png
│ │ dst202009241558584.png
│ │ dst202009241558585.png
│ │ dst202009241558586.png
│ │ dst202009241558587.png
│ │ dst202009241558588.png
│ │ dst202009241558589.png
│ │ haarcascade_frontalface_alt.xml
│ │
│ ├─dst
│ │ 1.txt
│ │
│ ├─org
│ │ └─developer
│ │ FaceDetector.class
│ │
│ └─src
│ 1001.JPG
│ 1002.JPG
│ 1003.JPG
│ 19.jpg
│ 20.jpg
│ 21.jpg
│ 22.jpg
│ 23.jpg
│ 24.jpg
│ 26.jpg
│ 27.jpg
│ 28.jpg
│ 31.jpg
│ 32.jpg
│ 33.jpg
│ 35.jpg
│ 36.jpg
│ five.jpg
│ group.jpg
│ many.JPG
│ ntest1.PNG
│ shekhar.JPG
│ timg.jpg
│ xiyou.JPG
│ zhuyin.JPG
│ zy.JPG
│
├─generated-sources
│ └─annotations
├─generated-test-sources
│ └─test-annotations
└─test-classes
└─org
└─developer
FaceDetectorTest.class
haarcascade_frontalface_alt.xml
这个文件会在最后有具体讲解的。
示例代码
/**
* opencv 入门示例
*
*/
public class FaceDetector
{
private static int imgCount = 0;
public static void main( String[] args )
{
//导入opencv
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("face-detector begin");
//采用opencv320\sources\data\haarcascades 安装目录里的 人脸检测器 haar特征
String xmlPath = FaceDetector.class.getResource("/haarcascade_frontalface_alt.xml").getPath().substring(1);
System.out.println("xmlPaht=" + xmlPath);
//检测的照片路径
String srcPath = FaceDetector.class.getResource("/src").getPath().substring(1);
//检测保存后的路径
String dstPath = FaceDetector.class.getResource("/dst").getPath().substring(1);
System.out.println("srcPaht=" + srcPath);
String imgsrc = srcPath + "/group2.jpg";
System.out.println("detection img=" + imgsrc);
//核心:加载xml识别配置文件,将图像转化为Mat对象后利用OpenCV函数进行识别,将识别到的人脸保存到 faceDetections
CascadeClassifier faceDetector = new CascadeClassifier(xmlPath);
Mat image = Imgcodecs.imread(imgsrc);
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);
System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String date = formatter.format(new Date());
for (Rect rect : faceDetections.toArray()) {
//画出人脸方框
Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255),3);
//将识别到的人脸剪切,并重新设置大小
Rect roi = new Rect(rect.x, rect.y, rect.width, rect.height);
Mat tmp = new Mat(image, roi);
Mat dst = tmp.clone();
Imgproc.resize(tmp, dst, new Size(160, 160));
//将人脸保存
String filename = dstPath + date + imgCount + ".png";
imgCount++;
System.out.println(String.format("Writing %s", filename));
Imgcodecs.imwrite(filename, dst);
}
String filename = dstPath + date +".png";
System.out.println(String.format("Writing %s", filename));
Imgcodecs.imwrite(filename, image);
}
}
原图1:
结果1:
原图2:
结果2:
等等,还没结束。。。,其实还是有翻车的地方:
原图3:
结果3:
上面的图片是基于 haarcascade_frontalface_alt.xml
这个分类器来分类的误差率较高。换成 haarcascade_frontalface_default.xml
这个分类器
结果4:
注:还是有五个人脸没识别,识别错误一个。
这个文件是 Opencv 内训练好的人脸检测分类器。
在 Opencv 中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征
和 LBL特征
。
在 Opencv 中,使用已经训练好的 XML 格式的分类器进行人脸检测。
在OpenCV的安装目录下的sources文件夹里的data文件夹里可以看到如下图所示的内容:
上图中文件夹的名字
“haarcascades”、“hogcascades” 和 “lbpcascades” 分别表示通过“haar”、“hog”和“lbp”三种不同的特征而训练出的分类器:即各文件夹里的文件。
打开 haarcascades
文件夹如下图所示:
#防丢失
haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml
haarcascade_frontalcatface.xml
haarcascade_frontalcatface_extended.xml
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
haarcascade_frontalface_alt_tree.xml
haarcascade_frontalface_default.xml
haarcascade_fullbody.xml
haarcascade_lefteye_2splits.xml
haarcascade_licence_plate_rus_16stages.xml
haarcascade_lowerbody.xml
haarcascade_profileface.xml
haarcascade_righteye_2splits.xml
haarcascade_russian_plate_number.xml
haarcascade_smile.xml
haarcascade_upperbody.xml