Java基于虹软实现人脸识别、人脸比对、活性检测等
虹软
- 免费,高级版本试用
- 支持在线、离线
- 有 Java SDK,C++ SDK
一、注册虹软开发者平台
点击注册
注册完成后可在“我的应用”中新建应用,获得 APP_ID
和 SDK_Key
,请记住这两个信息,后续 SDK 中会用到。
接下来下载SDK就行了。
二、开始使用SDK
SDK包结构
在下载的sdk包中,包结构大概是这样
|—demo
| |—ArcFaceDemo Demo工程
|—doc
| |—ARCSOFT_ARC_FACE_DEVELOPER’S_GUIDE.PDF 开发说明文档
|—inc
| |—amcomdef.h 平台文件
| |—asvloffscreen.h 平台文件
| |—arcsoft_face_sdk.h 接口文件
| |—merror.h 错误码文件
|—lib
|—|---Win32/x64
| |—|---libarcsoft_face.dll 算法库
| |—|---libarcsoft_face_engine.dll 引擎库
| |—|---libarcsoft_face_engine.lib 引擎库
|—samplecode
| |—samplecode.cpp 示例代码
|—releasenotes.txt 说明文件
在项目中引入 SDK 包
<dependency> <groupId>arcsoft</groupId> <artifactId>arcsoft-sdk-face</artifactId> <version>3.0.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/arcsoft-sdk-face-3.0.0.0.jar</systemPath> </dependency>
简单的集成
package com.study; import com.arcsoft.face.*; import com.arcsoft.face.enums.*; import com.arcsoft.face.toolkit.ImageFactory; import com.arcsoft.face.toolkit.ImageInfo; import com.arcsoft.face.toolkit.ImageInfoEx; import com.study.exception.CustomException; import com.study.vo.FaceDetailInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.List; /** * 集成虹软-人脸识别测试 * * @author ouyangrongtao * @since 2022-02-20 19:12 */ public class FaceEngineMain { // 从上述的开发者平台-“我的应用” 获取 private static final String APP_ID = ""; private static final String SDK_KEY = ""; // sdk安装路径 private static final String ARC_FACE_PATH = "arcsoft"; private static final Logger LOGGER = LoggerFactory.getLogger(FaceEngineMain.class); public static void main(String[] args) { FaceEngineMain faceEngineMain = new FaceEngineMain(); // 激活 FaceEngine faceEngine = faceEngineMain.active(); // 识别功能配置 FunctionConfiguration functionConfiguration = faceEngineMain.getFunctionConfiguration(); // 初始化识别引擎 faceEngineMain.initEngine(faceEngine, functionConfiguration); ImageInfo imageInfo = ImageFactory.getRGBData(new File("d:\\aaa.jpeg")); ImageInfo imageInfo2 = ImageFactory.getRGBData(new File("d:\\bbb.jpeg")); // 人脸检测&特征提取1 List<FaceDetailInfo> faceDetailInfoList1 = faceEngineMain.detectFaces(faceEngine, imageInfo); // 人脸检测&特征提取2 List<FaceDetailInfo> faceDetailInfoList2 = faceEngineMain.detectFaces(faceEngine, imageInfo2); /* * 特征比对 * 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82 * 用于生活照之间的特征比对,推荐阈值0.80 */ FaceSimilar faceSimilar = faceEngineMain.compareFaceFeature(faceEngine, faceDetailInfoList1.get(0).getFaceFeature(), faceDetailInfoList2.get(0).getFaceFeature()); LOGGER.info("相似度:{}", faceSimilar.getScore()); // 获取人脸属性 faceEngineMain.getFaceAttributes(faceEngine, imageInfo); ImageInfo imageInfo3 = ImageFactory.getRGBData(new File("d:\\ccc.jpg")); ImageInfo imageInfo4 = ImageFactory.getRGBData(new File("d:\\ddd.jpg")); // 人脸检测&特征提取3 List<FaceDetailInfo> faceDetailInfoList3 = faceEngineMain.detectFacesEx(faceEngine, imageInfo3, DetectModel.ASF_DETECT_MODEL_RGB); // 人脸检测&特征提取4 List<FaceDetailInfo> faceDetailInfoList4 = faceEngineMain.detectFacesEx(faceEngine, imageInfo4, DetectModel.ASF_DETECT_MODEL_RGB); // 特征比对 FaceSimilar faceSimilar2 = faceEngineMain.compareFaceFeature(faceEngine, faceDetailInfoList3.get(0).getFaceFeature(), faceDetailInfoList4.get(0).getFaceFeature(), CompareModel.LIFE_PHOTO); /* * 特征比对 * 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82 * 用于生活照之间的特征比对,推荐阈值0.80 */ LOGGER.info("相似度:{}", faceSimilar2.getScore()); // 获取人脸属性 faceEngineMain.getFaceAttributesEx(faceEngine, imageInfo); ImageInfo imageInfoGray = ImageFactory.getGrayData(new File("d:\\ddd.jpg")); // 活体检测 RGB & IR faceEngineMain.getLiveness(faceEngine, imageInfo, imageInfoGray); // 卸载 faceEngineMain.unInit(faceEngine); } /** * 活体检测 * @param faceEngine 引擎 * @param imageInfoRGB RGB图片信息 * @param imageInfoGray Gray图片信息 */ private void getLiveness(FaceEngine faceEngine, ImageInfo imageInfoRGB, ImageInfo imageInfoGray) { // 人脸检测 List<FaceInfo> faceInfoList = new ArrayList<>(); faceEngine.detectFaces(imageInfoRGB.getImageData(), imageInfoRGB.getWidth(), imageInfoRGB.getHeight(), imageInfoRGB.getImageFormat(), faceInfoList); // 设置活体测试阀值 faceEngine.setLivenessParam(0.5f, 0.7f); // RGB人脸检测 FunctionConfiguration configuration = new FunctionConfiguration(); configuration.setSupportLiveness(true); faceEngine.process(imageInfoRGB.getImageData(), imageInfoRGB.getWidth(), imageInfoRGB.getHeight(), imageInfoRGB.getImageFormat(), faceInfoList, configuration); // RGB活体检测 List<LivenessInfo> livenessInfoList = new ArrayList<>(); faceEngine.getLiveness(livenessInfoList); LOGGER.info("RGB活体:{}", livenessInfoList.get(0).getLiveness()); // IR属性处理 List<FaceInfo> faceInfoListGray = new ArrayList<>(); // IR人脸检查 faceEngine.detectFaces(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray); configuration = new FunctionConfiguration(); configuration.setSupportIRLiveness(true); faceEngine.processIr(imageInfoGray.getImageData(), imageInfoGray.getWidth(), imageInfoGray.getHeight(), imageInfoGray.getImageFormat(), faceInfoListGray, configuration); //IR活体检测 List<IrLivenessInfo> irLivenessInfo = new ArrayList<>(); faceEngine.getLivenessIr(irLivenessInfo); LOGGER.info("IR活体:{}", irLivenessInfo.get(0).getLiveness()); } /** * 人脸属性检测 * @param faceEngine 引擎 * @param imageInfo 图片信息 */ private void getFaceAttributesEx(FaceEngine faceEngine, ImageInfo imageInfo) { // 人脸检测 List<FaceInfo> faceInfoList = new ArrayList<>(); faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); ImageInfoEx imageInfoEx = new ImageInfoEx(); imageInfoEx.setHeight(imageInfo.getHeight()); imageInfoEx.setWidth(imageInfo.getWidth()); imageInfoEx.setImageFormat(imageInfo.getImageFormat()); imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()}); imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3}); //人脸属性检测 FunctionConfiguration configuration = new FunctionConfiguration(); configuration.setSupportGender(true); configuration.setSupportAge(true); configuration.setSupportFace3dAngle(true); faceEngine.process(imageInfoEx, faceInfoList, configuration); //性别检测 List<GenderInfo> genderInfoList = new ArrayList<>(); faceEngine.getGender(genderInfoList); LOGGER.info("性别:{}", genderInfoList.get(0).getGender()); //年龄检测 List<AgeInfo> ageInfoList = new ArrayList<>(); faceEngine.getAge(ageInfoList); LOGGER.info("年龄:{}", ageInfoList.get(0).getAge()); //3D信息检测 List<Face3DAngle> face3DAngleList = new ArrayList<>(); faceEngine.getFace3DAngle(face3DAngleList); Face3DAngle face3DAngle = face3DAngleList.get(0); LOGGER.info("3D角度:{}", face3DAngle.getPitch() + "," + face3DAngle.getRoll() + "," + face3DAngle.getYaw()); } /** * 人脸属性检测 * @param faceEngine 引擎 * @param imageInfo 图片信息 */ private void getFaceAttributes(FaceEngine faceEngine, ImageInfo imageInfo) { //人脸属性检测 FunctionConfiguration configuration = new FunctionConfiguration(); configuration.setSupportGender(true); configuration.setSupportAge(true); configuration.setSupportFace3dAngle(true); // 人脸检测 List<FaceInfo> faceInfoList = new ArrayList<>(); faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, configuration); //性别检测 List<GenderInfo> genderInfoList = new ArrayList<>(); faceEngine.getGender(genderInfoList); LOGGER.info("性别:{}", genderInfoList.get(0).getGender()); //年龄检测 List<AgeInfo> ageInfoList = new ArrayList<>(); faceEngine.getAge(ageInfoList); LOGGER.info("年龄:{}", ageInfoList.get(0).getAge()); //3D信息检测 List<Face3DAngle> face3DAngleList = new ArrayList<>(); faceEngine.getFace3DAngle(face3DAngleList); Face3DAngle face3DAngle = face3DAngleList.get(0); LOGGER.info("3D角度:{}", face3DAngle.getPitch() + "," + face3DAngle.getRoll() + "," + face3DAngle.getYaw()); } /** * 特征比对-可设置比对模型 * @param faceEngine 引擎 * @param sourceFaceFeature 原特征值 * @param targetFaceFeature 比对的特征值 * @param compareModel 比对模型 * @return 比对结果 */ private FaceSimilar compareFaceFeature(FaceEngine faceEngine, FaceFeature sourceFaceFeature, FaceFeature targetFaceFeature, CompareModel compareModel) { // 特征比对 FaceSimilar faceSimilar = new FaceSimilar(); int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, compareModel, faceSimilar); if (ErrorInfo.MOK.getValue() != errorCode) { LOGGER.error("人脸特征比对失败"); } return faceSimilar; } /** * 特征比对 * @param faceEngine 引擎 * @param sourceFaceFeature 原特征值 * @param targetFaceFeature 比对的特征值 * @return 比对结果 */ private FaceSimilar compareFaceFeature(FaceEngine faceEngine, FaceFeature sourceFaceFeature, FaceFeature targetFaceFeature) { // 特征比对 FaceSimilar faceSimilar = new FaceSimilar(); int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar); if (ErrorInfo.MOK.getValue() != errorCode) { LOGGER.error("人脸特征比对失败"); } return faceSimilar; } /** * 人脸检测&特征提取--可设置检测模式 * @param faceEngine 引擎 * @param imageInfo 图片信息 * @param detectModel 检测模式 * @return 人脸信息 */ private List<FaceDetailInfo> detectFacesEx(FaceEngine faceEngine, ImageInfo imageInfo, DetectModel detectModel) { ImageInfoEx imageInfoEx = new ImageInfoEx(); imageInfoEx.setHeight(imageInfo.getHeight()); imageInfoEx.setWidth(imageInfo.getWidth()); imageInfoEx.setImageFormat(imageInfo.getImageFormat()); imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()}); imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3}); List<FaceInfo> faceInfoList = new ArrayList<>(); faceEngine.detectFaces(imageInfoEx, detectModel, faceInfoList); List<FaceDetailInfo> faceDetailInfoList = new ArrayList<>(faceInfoList.size()); for (FaceInfo faceInfo : faceInfoList) { LOGGER.info("imageInfoEx 人脸检测结果: {}", faceInfo); FaceFeature faceFeature = new FaceFeature(); faceEngine.extractFaceFeature(imageInfoEx, faceInfo, faceFeature); LOGGER.info("imageInfoEx 特征值大小:{}", faceFeature.getFeatureData().length); FaceDetailInfo faceDetailInfo = new FaceDetailInfo(faceInfo, faceFeature); faceDetailInfoList.add(faceDetailInfo); } return faceDetailInfoList; } /** * 人脸检测&特征提取 * @param faceEngine 引擎 * @param imageInfo 图片信息 * @return 人脸信息 */ private List<FaceDetailInfo> detectFaces(FaceEngine faceEngine, ImageInfo imageInfo) { // 人脸检测 List<FaceInfo> faceInfoList = new ArrayList<>(); faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList); List<FaceDetailInfo> faceDetailInfoList = new ArrayList<>(faceInfoList.size()); // 特征提取 for (FaceInfo faceInfo : faceInfoList) { LOGGER.info("人脸检测结果: {}", faceInfo); FaceFeature faceFeature = new FaceFeature(); faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfo, faceFeature); LOGGER.info("特征值大小:{}", faceFeature.getFeatureData().length); FaceDetailInfo faceDetailInfo = new FaceDetailInfo(faceInfo, faceFeature); faceDetailInfoList.add(faceDetailInfo); } return faceDetailInfoList; } /** * 初始化识别引擎 * @param faceEngine 人脸识别引擎 * @param functionConfiguration 功能配置 */ private void initEngine(FaceEngine faceEngine, FunctionConfiguration functionConfiguration) { // 引擎配置 EngineConfiguration engineConfiguration = new EngineConfiguration(); engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE); engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT); engineConfiguration.setDetectFaceMaxNum(10); engineConfiguration.setDetectFaceScaleVal(16); engineConfiguration.setFunctionConfiguration(functionConfiguration); // 初始化引擎 int errorCode = faceEngine.init(engineConfiguration); if (errorCode != ErrorInfo.MOK.getValue()) { throw new CustomException("初始化引擎失败"); } } /** * 识别功能配置 */ private FunctionConfiguration getFunctionConfiguration() { // 功能配置 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); return functionConfiguration; } /** * 激活 初次使用SDK时需要对SDK先进行激活,激活后无需重复调用;调用此接口时必须为联网状态,激活成功后即可离线使用; * @return FaceEngine 对象 */ private FaceEngine active() { URL resource = ClassLoader.getSystemResource(ARC_FACE_PATH); LOGGER.info("软件安装目录:{}", resource); FaceEngine faceEngine = new FaceEngine(resource.getPath()); ActiveFileInfo activeFileInfo = new ActiveFileInfo(); int errorCode = faceEngine.getActiveFileInfo(activeFileInfo); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { LOGGER.info("获取激活文件信息失败"); } // 首次激活 errorCode = faceEngine.activeOnline(APP_ID, SDK_KEY); if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) { throw new CustomException("引擎激活失败"); } LOGGER.info("激活信息:{}", activeFileInfo); return faceEngine; } /** * 卸载引擎 * @param faceEngine 人脸识别引擎 */ private void unInit(FaceEngine faceEngine) { faceEngine.unInit(); } }
性能信息(参考官方文档)
阀值设置推荐(参考官方文档)
1. 活体取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为活体。 - RGB 活体:0.5 - IR 活体:0.7 2. 人脸比对取值范围为[0~1],推荐阈值如下,高于此阈值的即可判断为同一人。 - 用于生活照之间的特征比对,推荐阈值0.80 - 用于证件照或生活照与证件照之间的特征比对,推荐阈值0.82
上一篇:springboot配置数据库密码特殊字符报错的解决
栏 目:JAVA代码
下一篇:SpringMVC RESTFul实战案例删除功能实现
本文标题:Java基于虹软实现人脸识别、人脸比对、活性检测等
本文地址:http://www.codeinn.net/misctech/215605.html