Java基于虹軟實(shí)現(xiàn)人臉識(shí)別、人臉比對(duì)、活性檢測(cè)等
虹軟
- 免費(fèi),高級(jí)版本試用
- 支持在線、離線
- 有 Java SDK,C++ SDK
一、注冊(cè)虹軟開(kāi)發(fā)者平臺(tái)
點(diǎn)擊注冊(cè)

注冊(cè)完成后可在“我的應(yīng)用”中新建應(yīng)用,獲得 APP_ID 和 SDK_Key,請(qǐng)記住這兩個(gè)信息,后續(xù) SDK 中會(huì)用到。

接下來(lái)下載SDK就行了。
二、開(kāi)始使用SDK
SDK包結(jié)構(gòu)
在下載的sdk包中,包結(jié)構(gòu)大概是這樣
|—demo
| |—ArcFaceDemo Demo工程
|—doc
| |—ARCSOFT_ARC_FACE_DEVELOPER’S_GUIDE.PDF 開(kāi)發(fā)說(shuō)明文檔
|—inc
| |—amcomdef.h 平臺(tái)文件
| |—asvloffscreen.h 平臺(tái)文件
| |—arcsoft_face_sdk.h 接口文件
| |—merror.h 錯(cuò)誤碼文件
|—lib
|—|---Win32/x64
| |—|---libarcsoft_face.dll 算法庫(kù)
| |—|---libarcsoft_face_engine.dll 引擎庫(kù)
| |—|---libarcsoft_face_engine.lib 引擎庫(kù)
|—samplecode
| |—samplecode.cpp 示例代碼
|—releasenotes.txt 說(shuō)明文件
在項(xiàng)目中引入 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>
簡(jiǎn)單的集成
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;
/**
* 集成虹軟-人臉識(shí)別測(cè)試
*
* @author ouyangrongtao
* @since 2022-02-20 19:12
*/
public class FaceEngineMain {
// 從上述的開(kāi)發(fā)者平臺(tái)-“我的應(yīng)用” 獲取
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();
// 識(shí)別功能配置
FunctionConfiguration functionConfiguration = faceEngineMain.getFunctionConfiguration();
// 初始化識(shí)別引擎
faceEngineMain.initEngine(faceEngine, functionConfiguration);
ImageInfo imageInfo = ImageFactory.getRGBData(new File("d:\\aaa.jpeg"));
ImageInfo imageInfo2 = ImageFactory.getRGBData(new File("d:\\bbb.jpeg"));
// 人臉檢測(cè)&特征提取1
List<FaceDetailInfo> faceDetailInfoList1 = faceEngineMain.detectFaces(faceEngine, imageInfo);
// 人臉檢測(cè)&特征提取2
List<FaceDetailInfo> faceDetailInfoList2 = faceEngineMain.detectFaces(faceEngine, imageInfo2);
/*
* 特征比對(duì)
* 用于證件照或生活照與證件照之間的特征比對(duì),推薦閾值0.82
* 用于生活照之間的特征比對(duì),推薦閾值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"));
// 人臉檢測(cè)&特征提取3
List<FaceDetailInfo> faceDetailInfoList3 = faceEngineMain.detectFacesEx(faceEngine, imageInfo3, DetectModel.ASF_DETECT_MODEL_RGB);
// 人臉檢測(cè)&特征提取4
List<FaceDetailInfo> faceDetailInfoList4 = faceEngineMain.detectFacesEx(faceEngine, imageInfo4, DetectModel.ASF_DETECT_MODEL_RGB);
// 特征比對(duì)
FaceSimilar faceSimilar2 = faceEngineMain.compareFaceFeature(faceEngine,
faceDetailInfoList3.get(0).getFaceFeature(), faceDetailInfoList4.get(0).getFaceFeature(), CompareModel.LIFE_PHOTO);
/*
* 特征比對(duì)
* 用于證件照或生活照與證件照之間的特征比對(duì),推薦閾值0.82
* 用于生活照之間的特征比對(duì),推薦閾值0.80
*/
LOGGER.info("相似度:{}", faceSimilar2.getScore());
// 獲取人臉屬性
faceEngineMain.getFaceAttributesEx(faceEngine, imageInfo);
ImageInfo imageInfoGray = ImageFactory.getGrayData(new File("d:\\ddd.jpg"));
// 活體檢測(cè) RGB & IR
faceEngineMain.getLiveness(faceEngine, imageInfo, imageInfoGray);
// 卸載
faceEngineMain.unInit(faceEngine);
}
/**
* 活體檢測(cè)
* @param faceEngine 引擎
* @param imageInfoRGB RGB圖片信息
* @param imageInfoGray Gray圖片信息
*/
private void getLiveness(FaceEngine faceEngine, ImageInfo imageInfoRGB, ImageInfo imageInfoGray) {
// 人臉檢測(cè)
List<FaceInfo> faceInfoList = new ArrayList<>();
faceEngine.detectFaces(imageInfoRGB.getImageData(),
imageInfoRGB.getWidth(), imageInfoRGB.getHeight(), imageInfoRGB.getImageFormat(), faceInfoList);
// 設(shè)置活體測(cè)試閥值
faceEngine.setLivenessParam(0.5f, 0.7f);
// RGB人臉檢測(cè)
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportLiveness(true);
faceEngine.process(imageInfoRGB.getImageData(),
imageInfoRGB.getWidth(), imageInfoRGB.getHeight(), imageInfoRGB.getImageFormat(), faceInfoList, configuration);
// RGB活體檢測(cè)
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活體檢測(cè)
List<IrLivenessInfo> irLivenessInfo = new ArrayList<>();
faceEngine.getLivenessIr(irLivenessInfo);
LOGGER.info("IR活體:{}", irLivenessInfo.get(0).getLiveness());
}
/**
* 人臉屬性檢測(cè)
* @param faceEngine 引擎
* @param imageInfo 圖片信息
*/
private void getFaceAttributesEx(FaceEngine faceEngine, ImageInfo imageInfo) {
// 人臉檢測(cè)
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});
//人臉屬性檢測(cè)
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportGender(true);
configuration.setSupportAge(true);
configuration.setSupportFace3dAngle(true);
faceEngine.process(imageInfoEx, faceInfoList, configuration);
//性別檢測(cè)
List<GenderInfo> genderInfoList = new ArrayList<>();
faceEngine.getGender(genderInfoList);
LOGGER.info("性別:{}", genderInfoList.get(0).getGender());
//年齡檢測(cè)
List<AgeInfo> ageInfoList = new ArrayList<>();
faceEngine.getAge(ageInfoList);
LOGGER.info("年齡:{}", ageInfoList.get(0).getAge());
//3D信息檢測(cè)
List<Face3DAngle> face3DAngleList = new ArrayList<>();
faceEngine.getFace3DAngle(face3DAngleList);
Face3DAngle face3DAngle = face3DAngleList.get(0);
LOGGER.info("3D角度:{}", face3DAngle.getPitch() + "," + face3DAngle.getRoll() + "," + face3DAngle.getYaw());
}
/**
* 人臉屬性檢測(cè)
* @param faceEngine 引擎
* @param imageInfo 圖片信息
*/
private void getFaceAttributes(FaceEngine faceEngine, ImageInfo imageInfo) {
//人臉屬性檢測(cè)
FunctionConfiguration configuration = new FunctionConfiguration();
configuration.setSupportGender(true);
configuration.setSupportAge(true);
configuration.setSupportFace3dAngle(true);
// 人臉檢測(cè)
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);
//性別檢測(cè)
List<GenderInfo> genderInfoList = new ArrayList<>();
faceEngine.getGender(genderInfoList);
LOGGER.info("性別:{}", genderInfoList.get(0).getGender());
//年齡檢測(cè)
List<AgeInfo> ageInfoList = new ArrayList<>();
faceEngine.getAge(ageInfoList);
LOGGER.info("年齡:{}", ageInfoList.get(0).getAge());
//3D信息檢測(cè)
List<Face3DAngle> face3DAngleList = new ArrayList<>();
faceEngine.getFace3DAngle(face3DAngleList);
Face3DAngle face3DAngle = face3DAngleList.get(0);
LOGGER.info("3D角度:{}", face3DAngle.getPitch() + "," + face3DAngle.getRoll() + "," + face3DAngle.getYaw());
}
/**
* 特征比對(duì)-可設(shè)置比對(duì)模型
* @param faceEngine 引擎
* @param sourceFaceFeature 原特征值
* @param targetFaceFeature 比對(duì)的特征值
* @param compareModel 比對(duì)模型
* @return 比對(duì)結(jié)果
*/
private FaceSimilar compareFaceFeature(FaceEngine faceEngine, FaceFeature sourceFaceFeature, FaceFeature targetFaceFeature, CompareModel compareModel) {
// 特征比對(duì)
FaceSimilar faceSimilar = new FaceSimilar();
int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, compareModel, faceSimilar);
if (ErrorInfo.MOK.getValue() != errorCode) {
LOGGER.error("人臉特征比對(duì)失敗");
}
return faceSimilar;
}
/**
* 特征比對(duì)
* @param faceEngine 引擎
* @param sourceFaceFeature 原特征值
* @param targetFaceFeature 比對(duì)的特征值
* @return 比對(duì)結(jié)果
*/
private FaceSimilar compareFaceFeature(FaceEngine faceEngine, FaceFeature sourceFaceFeature, FaceFeature targetFaceFeature) {
// 特征比對(duì)
FaceSimilar faceSimilar = new FaceSimilar();
int errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
if (ErrorInfo.MOK.getValue() != errorCode) {
LOGGER.error("人臉特征比對(duì)失敗");
}
return faceSimilar;
}
/**
* 人臉檢測(cè)&特征提取--可設(shè)置檢測(cè)模式
* @param faceEngine 引擎
* @param imageInfo 圖片信息
* @param detectModel 檢測(cè)模式
* @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 人臉檢測(cè)結(jié)果: {}", 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;
}
/**
* 人臉檢測(cè)&特征提取
* @param faceEngine 引擎
* @param imageInfo 圖片信息
* @return 人臉信息
*/
private List<FaceDetailInfo> detectFaces(FaceEngine faceEngine, ImageInfo imageInfo) {
// 人臉檢測(cè)
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("人臉檢測(cè)結(jié)果: {}", 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;
}
/**
* 初始化識(shí)別引擎
* @param faceEngine 人臉識(shí)別引擎
* @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("初始化引擎失敗");
}
}
/**
* 識(shí)別功能配置
*/
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時(shí)需要對(duì)SDK先進(jìn)行激活,激活后無(wú)需重復(fù)調(diào)用;調(diào)用此接口時(shí)必須為聯(lián)網(wǎng)狀態(tài),激活成功后即可離線使用;
* @return FaceEngine 對(duì)象
*/
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 人臉識(shí)別引擎
*/
private void unInit(FaceEngine faceEngine) {
faceEngine.unInit();
}
}
性能信息(參考官方文檔)

閥值設(shè)置推薦(參考官方文檔)
1. 活體取值范圍為[0~1],推薦閾值如下,高于此閾值的即可判斷為活體。
- RGB 活體:0.5
- IR 活體:0.7
2. 人臉比對(duì)取值范圍為[0~1],推薦閾值如下,高于此閾值的即可判斷為同一人。
- 用于生活照之間的特征比對(duì),推薦閾值0.80
- 用于證件照或生活照與證件照之間的特征比對(duì),推薦閾值0.82
產(chǎn)品文檔 https://ai.arcsoft.com.cn/manual/docs#/89
到此這篇關(guān)于Java基于虹軟實(shí)現(xiàn)人臉識(shí)別、人臉比對(duì)、活性檢測(cè)等的文章就介紹到這了,更多相關(guān)Java 人臉識(shí)別、人臉比對(duì)、活性檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java+opencv實(shí)現(xiàn)人臉識(shí)別功能
- Java OpenCV實(shí)現(xiàn)人臉識(shí)別過(guò)程詳解
- Java OpenCV4.0.0實(shí)現(xiàn)實(shí)時(shí)人臉識(shí)別
- OpenCV Java實(shí)現(xiàn)人臉識(shí)別和裁剪功能
- OPENCV+JAVA實(shí)現(xiàn)人臉識(shí)別
- JavaCV調(diào)用百度AI實(shí)現(xiàn)人臉檢測(cè)方法詳解
- Java+OpenCV實(shí)現(xiàn)人臉檢測(cè)并自動(dòng)拍照
- java騰訊AI人臉對(duì)比對(duì)接代碼實(shí)例
- Java+opencv3.2.0實(shí)現(xiàn)人臉檢測(cè)功能
- JavaCV實(shí)現(xiàn)人臉檢測(cè)功能
相關(guān)文章
SpringBoot實(shí)現(xiàn)單文件與多文件上傳
本次例子不基于第三方存儲(chǔ)(如七牛云對(duì)象存儲(chǔ)、阿里云對(duì)象存儲(chǔ)、騰訊云對(duì)象存儲(chǔ)等),僅基于本地存儲(chǔ)。本文主要內(nèi)容如下:公共文件存儲(chǔ)代碼;單文件上傳代碼;多文件上傳代碼2021-05-05
Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析
這篇文章主要介紹了Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
Jsoup獲取全國(guó)地區(qū)數(shù)據(jù)屬性值(省市縣鎮(zhèn)村)
這篇文章主要介紹了Jsoup獲取全國(guó)地區(qū)數(shù)據(jù)屬性值(省市縣鎮(zhèn)村)的相關(guān)資料,需要的朋友可以參考下2015-10-10
java 中的instanceof用法詳解及instanceof是什么意思(推薦)
instanceof 是 Java 的保留關(guān)鍵字。它的作用是測(cè)試它左邊的對(duì)象是否是它右邊的類(lèi)的實(shí)例,返回 boolean 的數(shù)據(jù)類(lèi)型。接下來(lái)通過(guò)本文給大家介紹java 中的instanceof用法詳解及instanceof是什么意思,需要的朋友參考下吧2017-11-11
java中將一個(gè)實(shí)體類(lèi)復(fù)制到另一個(gè)實(shí)體類(lèi)的3種方法示例
這篇文章主要給大家介紹了關(guān)于java中將一個(gè)實(shí)體類(lèi)復(fù)制到另一個(gè)實(shí)體類(lèi)的3種方法,所謂實(shí)體類(lèi)就是一個(gè)擁有Set和Get方法的類(lèi),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07

