Java基于虹软实现人脸识别、人脸比对、活性检测等
作者:lytao123 发布时间:2023-02-18 15:29:09
虹软
免费,高级版本试用
支持在线、离线
有 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
产品文档 https://ai.arcsoft.com.cn/manual/docs#/89
来源:https://blog.csdn.net/qq_24598601/article/details/123038394
猜你喜欢
- 图片上传功能是我们web里面经常用到的,获得的方式也有很多种,这里我用的是request.getInputStream()获取文件流的方式。
- 因为某个项目需要,为团队其他兄弟姐妹开发了一个 XML 分析处理器,并将其设计为一个类库,提供相应的 API 接口。为了方便大家的使用,需要
- 前言:List 去重指的是将 List 中的重复元素删除掉的过程。此题目考察的是对 List 迭代器、Set 集合和 JDK 8 中新特性的
- yml文件参数的读取附上一个较为常见的application.yml文件示例server: port: 9999 u
- 前言人类建造迷宫已有5000年的历史。在世界的不同文化发展时期,这些奇特的建筑物始终吸引人们沿着弯弯曲曲、困难重重的小路吃力地行走,寻找真相
- java 线程锁在Java线程中运用synchronized关键字来达到同步的 synchronized可以锁方法,锁类,锁对象,锁代码块方
- 我们在学习接口的时候。能够在里面做一些方法的调用。不过今天所要讲的JDBC,虽然也是连接数据库的一种接口,不过与类接口有着很大的区别,大家要
- 本文实例为大家分享了Java实现抢红包功能的具体代码,供大家参考,具体内容如下关键思想:1.抢红包涉及多人并发操作,需要做好同步保证多线程运
- 我们在项目中都会遇到项目打包,可以通过assembly对我们的项目进行打包。针对打包构建jar包,本文不再叙述。具体可以参考maven插件a
- java 中 System.out.println()和System.out.write()的区别.这两个函数一个是System
- 1.spring boot * 默认有:HandlerInterceptorAdapterAbstractHandlerMappingUse
- 前言前一篇文章我们熟悉了HikariCP连接池,也了解到它的性能很高,今天我们讲一下另一款比较受欢迎的连接池:Druid,这是阿里开源的一款
- 接收到这样一个需求,就是英文名字中firstName和lastName,其中任何一个为null,就返回Empty。刚拿到需求,这不简单,if
- 本文实例讲述了java实现图片写入高清字体及带边框的方法。分享给大家供大家参考。具体实现方法如下:Graphics2D g2=image.c
- 前言Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.
- SpringMVC常用组件DispatcherServlet:前端控制器,不需要工程师开发,由框架提供作用:统一处理请求和响应,整个流程控制
- 本文实例为大家分享了Unity实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下一、演示二、实现思路创建每一个方块可移动到的位置点,可以
- 一、项目运行环境配置:Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe
- 测试类中的问题和解决思路问题在测试类中,每个测试方法都有以下两行代码:ApplicationContext ac = new ClassPa
- 一、常规形式1 项目结构2 配置文件及环境设置(1)配置文件# 应用服务 WEB 访问端口server.port=8080# spring