openCV人脸检测和人脸识别
学习内容:
1、 javaCV依赖
2、 人脸检测
3、 人脸比对
依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
<version>3.4.3-1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
<version>3.4.3-1.4.3</version>
</dependency>
人脸检测
- 启动本地摄像头
0代表本地
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start(); // 开始获取摄像头数据
ShowCamera.init(grabber);
当前人脸中加入了检测到人脸后,获取人脸特征并做标记
2. 检测人脸
public static RectVector findFaces(Mat image) {
Mat imageGray = FaceAndEyeToos.doColorHist(image);
//进行人脸识别
RectVector faceDetections = new RectVector();
faceDetector.detectMultiScale(imageGray, faceDetections);
if(faceDetections.empty()){
return null;
}
return faceDetections;
}
效果同图一
3. 人脸比对
比对时查找本地人脸库中是否存在相似人脸照片
public static List<Face> findPeople(Mat oriFrame,RectVector faces) {
Mat imageGray = FaceAndEyeToos.doColorHist(oriFrame);
//getTainFile(faceRecognizer);
Mat saveFace = null;
List<Face> result = Lists.newArrayList();
for (Rect rect : faces.get()) {
saveFace = new Mat(imageGray, rect);
opencv_imgproc.resize(saveFace, saveFace, new Size(Common.faceWidth, Common.faceHeight));
//人脸对齐
IntPointer label = new IntPointer(4);
DoublePointer confidence = new DoublePointer(8);
faceRecognizer.predict(saveFace, label, confidence);
int predictedLabel = label.get(0);
System.out.println(predictedLabel);
if(predictedLabel != 0){
//查找到当前人员信息直接返回
result.add(FaceList.getFace(predictedLabel-1));
}else{
continue;
}
}
return result;
}
- 保存人脸图像
不存在则保存人脸图像功能
public static void saveFace(RectVector faces,Mat oriFrame,boolean addToModel){
if(faces == null || faces.empty()){
return ;
}
Mat imageGray = doColorHist(oriFrame);
Mat saveFace = null;
for (Rect rect : faces.get()) {
saveFace = new Mat(oriFrame, rect);
opencv_imgproc.resize(saveFace, saveFace, new Size(Common.faceWidth,Common.faceHeight));
if(saveFace.sizeof() > 0){
doSave(saveFace,Common.saveFacePath,addToModel);
}
}
saveFace.close();
imageGray.close();
}
第一次会保存新的人脸,图片暂不展示
5. 训练模型 功能
public static void train(){
int faceSize = FaceList.getFaceFiles().size();
MatVector images = new MatVector(faceSize+1);
Mat labels = new Mat(faceSize+1, 1,opencv_core.CV_32SC1);
IntBuffer labelsBuf = labels.createBuffer();
labelsBuf.put(0,0);
images.put(0,FaceList.getFace(PathUtil.getFilePath(Common.invalidFace)));
for (int i = 1; i < faceSize+1; i++) {
Face p = FaceList.getFaceFiles().get(i-1);
images.put(i, p.getFaceMat());
labelsBuf.put(i, i);
}
faceRecognizer.train(images, labels);
saveTainFile(faceRecognizer);
}
人脸模型则自动训练
总结
目前人脸比功能和实际使用差距比较大,下一步将添加检测多个人脸,采用多线程去操作人脸比对,同时人脸比对为了提高识别结果,将结合Eigenface特征脸识别 (PCA)和Fisherface(LDA)线性判别分析,同一个结果检测两次,然后作为最终结果参考,同时在照片比对前,将获取到的人脸照片分多次转换以提高比对质量。