视频人脸识别系列
第一篇 使用openCV进行视频人脸识别
第二篇 使用虹软SDK进行视频人脸识别
第三篇 使用虹软SDK进行视频人脸比对
文章目录
前言
发现了一个可以免费使用的人脸识别库,虹软SDK,高级功能是需要收费的,集成一个SDK看看效果。
一、环境依赖
开发环境
- javaJdk 11
- Apache Maven 3.8.4
- 虹软 sdk java 3.0
- IDEA 2021.3 CE 社区版
java 环境搭建见 第一篇 使用openCV进行视频人脸识别
申请虹软KEY
注册虹软账号,创建应用,选择对应平台后得到key,并下载SDK备用。
maven 项目集成虹软sdk
引入sdk库
在项目根目录创建 libs 库 将下载的虹软SDK解压把里面的 arcsoft-sdk-face-3.0.0.0.jar 放入 libs 目录。并把 WIN64 目录也放在该目录下或者把WIN64放在别的目录也可以。
在 pom.xml 添加引用
<dependencies>
<!-- 虹软sdk -->
<dependency>
<groupId>com.arcsoft.face</groupId>
<artifactId>arcsoft-sdk-face</artifactId>
<version>3.0.0.0</version>
<scope>system</scope>
<systemPath>${basedir}/libs/arcsoft-sdk-face-3.0.0.0.jar</systemPath>
</dependency>
<!-- javaCV库 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.7</version>
<type>pom</type>
</dependency>
</dependencies>
二、使用虹软SDK进行人脸识别
在线激活SDK 和 获取授权文件信息
//从官网获取的key
String appId = "给你分配的ID";
String sdkKey = "你申请的key";
String sdkLibPath = "D:\\javaworks\\faceDemo\\libs\\WIN64";
//指定引擎依赖库
FaceEngine faceEngine = new FaceEngine(sdkLibPath);
//激活引擎
int errorCode = faceEngine.activeOnline(appId, sdkKey);
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("引擎激活失败");
System.exit(2);
}
//获取激活文件
ActiveFileInfo activeFileInfo=new ActiveFileInfo();
errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("获取激活文件信息失败");
System.exit(2);
}
初始化引擎
//引擎配置
EngineConfiguration engineConfiguration = new EngineConfiguration();
// engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_VIDEO);
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
// engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
engineConfiguration.setDetectFaceMaxNum(10);
engineConfiguration.setDetectFaceScaleVal(16); //视频推荐16 图片推荐32
//功能配置
FunctionConfiguration functionConfiguration = new FunctionConfiguration();
functionConfiguration.setSupportAge(true);
functionConfiguration.setSupportFace3dAngle(true);
functionConfiguration.setSupportFaceDetect(true);
functionConfiguration.setSupportFaceRecognition(true);
functionConfiguration.setSupportGender(true);
functionConfiguration.setSupportLiveness(true);
functionConfiguration.setSupportIRLiveness(true);
engineConfiguration.setFunctionConfiguration(functionConfiguration);
//初始化引擎
errorCode = faceEngine.init(engineConfiguration);
if (errorCode != ErrorInfo.MOK.getValue()) {
System.out.println("初始化引擎失败");
System.exit(2);
}
从设备获取视频帧
//抓取摄像头
grabber = new OpenCVFrameGrabber(0);
// grabber.setFrameRate(24);
grabber.setImageWidth(960);
grabber.setImageHeight(540);
grabber.start();
循环提取每帧图片上的人脸信息
// frame = grabber.grabImage();
frame = grabber.grab();
IplImage iplImage = converter.convert(frame);
byte[] imageData = new byte[iplImage.imageSize()];
iplImage.imageData().get(imageData);
//提取人脸信息
List<FaceInfo> imageInfoList = new LinkedList<>();
errorCode = faceEngine.detectFaces(imageData, iplImage.width(), iplImage.height(), ImageFormat.CP_PAF_BGR24, imageInfoList);
int faceNum = imageInfoList.size();
人脸属性检查
//人脸属性检测
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportAge(true);
configuration.setSupportGender(true);
errorCode = faceEngine.process(imageData, iplImage.width(), iplImage.height(), ImageFormat.CP_PAF_BGR24, imageInfoList, configuration);
//性别检测
List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
errorCode = faceEngine.getGender(genderInfoList);
//年龄检测
List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
errorCode = faceEngine.getAge(ageInfoList);
把人脸框出来
//人脸画框
for(int i = 0; i<imageInfoList.size(); i++){
int x = imageInfoList.get(i).getRect().getLeft();
int y = imageInfoList.get(i).getRect().getTop();
int xMax = imageInfoList.get(i).getRect().getRight();
int yMax = imageInfoList.get(i).getRect().getBottom();
int gender = genderInfoList.size()>0 ? genderInfoList.get(i).getGender() : -1;
int age = ageInfoList.size()>0 ? ageInfoList.get(i).getAge() : -1;
String info = gender + ":" + age;
CvScalar cvScalar = cvScalar(0,0,255,0);
CvPoint cvPoint = cvPoint(x,y);
CvPoint cvPoint1 = cvPoint(xMax,yMax);
opencv_imgproc.cvRectangle(iplImage, cvPoint, cvPoint1,cvScalar,1,4,0);
//中文显示乱码不知道怎么办 有知道的请指教谢谢
opencv_imgproc.cvPutText(iplImage,info,cvPoint(xMax,y+10),cvFont(1.0),cvScalar);
}
//图片刷新到窗口
frame = converter.convert(iplImage);
canvasFrame.showImage(frame);
来个完整的
package com.sxfenglei;
import com.arcsoft.face.*;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.DetectOrient;
import com.arcsoft.face.enums.ErrorInfo;
import com.arcsoft.face.enums.ImageFormat;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import static org.bytedeco.opencv.global.opencv_core.cvPoint;
import static org.bytedeco.opencv.global.opencv_core.cvScalar;
import static org.bytedeco.opencv.global.opencv_imgproc.cvFont;
public class AppDemo {
public static void main(String[] args) {
//从官网获取的key
String appId = "给你分配的ID";
String sdkKey = "你申请的key";
String sdkLibPath = "D:\\javaworks\\faceDemo\\libs\\WIN64";
//指定引擎依赖库
FaceEngine faceEngine = new FaceEngine(sdkLibPath);
//激活引擎
int errorCode = faceEngine.activeOnline(appId, sdkKey);
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("引擎激活失败");
System.exit(2);
}
//获取激活文件
ActiveFileInfo activeFileInfo=new ActiveFileInfo();
errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
System.out.println("获取激活文件信息失败");
System.exit(2);
}
//引擎配置
EngineConfiguration engineConfiguration = new EngineConfiguration();
// engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_VIDEO);
engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
// engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
engineConfiguration.setDetectFaceMaxNum(10);
engineConfiguration.setDetectFaceScaleVal(16); //视频推荐16 图片推荐32
//功能配置
FunctionConfiguration functionConfiguration = new FunctionConfiguration();
functionConfiguration.setSupportAge(true);
functionConfiguration.setSupportFace3dAngle(true);
functionConfiguration.setSupportFaceDetect(true);
functionConfiguration.setSupportFaceRecognition(true);
functionConfiguration.setSupportGender(true);
functionConfiguration.setSupportLiveness(true);
functionConfiguration.setSupportIRLiveness(true);
engineConfiguration.setFunctionConfiguration(functionConfiguration);
//初始化引擎
errorCode = faceEngine.init(engineConfiguration);
if (errorCode != ErrorInfo.MOK.getValue()) {
System.out.println("初始化引擎失败");
System.exit(2);
}
//本地摄像头视频进行人脸识别
OpenCVFrameGrabber grabber = null; //帧抓取器
try{
//抓取摄像头
grabber = new OpenCVFrameGrabber(0);
// grabber.setFrameRate(24);
grabber.setImageWidth(960);
grabber.setImageHeight(540);
grabber.start();
//新建窗口
CanvasFrame canvasFrame = new CanvasFrame("摄像头");
canvasFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
canvasFrame.setAlwaysOnTop(true);
//转换
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
Frame frame = null;
while (true) {
if (!canvasFrame.isDisplayable()) {
grabber.stop();
System.out.println("退出");
System.exit(2);
}
// frame = grabber.grabImage();
frame = grabber.grab();
IplImage iplImage = converter.convert(frame);
byte[] imageData = new byte[iplImage.imageSize()];
iplImage.imageData().get(imageData);
//提取人脸信息
List<FaceInfo> imageInfoList = new LinkedList<>();
errorCode = faceEngine.detectFaces(imageData, iplImage.width(), iplImage.height(), ImageFormat.CP_PAF_BGR24, imageInfoList);
int faceNum = imageInfoList.size();
if(faceNum > 0){
System.out.println("提取到"+faceNum+"个人脸");
//人脸属性检测
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportAge(true);
configuration.setSupportGender(true);
errorCode = faceEngine.process(imageData, iplImage.width(), iplImage.height(), ImageFormat.CP_PAF_BGR24, imageInfoList, configuration);
//性别检测
List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
errorCode = faceEngine.getGender(genderInfoList);
//年龄检测
List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
errorCode = faceEngine.getAge(ageInfoList);
//人脸画框
for(int i = 0; i<imageInfoList.size(); i++){
int x = imageInfoList.get(i).getRect().getLeft();
int y = imageInfoList.get(i).getRect().getTop();
int xMax = imageInfoList.get(i).getRect().getRight();
int yMax = imageInfoList.get(i).getRect().getBottom();
int gender = genderInfoList.size()>0 ? genderInfoList.get(i).getGender() : -1;
int age = ageInfoList.size()>0 ? ageInfoList.get(i).getAge() : -1;
String info = gender + ":" + age;
CvScalar cvScalar = cvScalar(0,0,255,0);
CvPoint cvPoint = cvPoint(x,y);
CvPoint cvPoint1 = cvPoint(xMax,yMax);
opencv_imgproc.cvRectangle(iplImage, cvPoint, cvPoint1,cvScalar,1,4,0);
//中文显示乱码不知道怎么办 有知道的请指教谢谢
opencv_imgproc.cvPutText(iplImage,info,cvPoint(xMax,y+10),cvFont(1.0),cvScalar);
}
}else{
System.out.print("未检测到人脸 ");
}
//图片刷新到窗口
frame = converter.convert(iplImage);
canvasFrame.showImage(frame);
}
}catch (Exception e){
System.out.println(e.getMessage());
}finally {
if(null != grabber){
try {
grabber.close();
} catch (FrameGrabber.Exception e) {
e.printStackTrace();
}
}
}
}
}
运行下比之前用的 haarcascade_frontalface_alt2.xml 识别度高很多。