springboot虹软人脸识别集成

准备工作

在这里插入图片描述
虹软开放平台中创建一个新的应用 虹软开发平台【点我跳转】

开始上代码

基本配置

在这里插入图片描述
将下载的jar包放到src同级目录下

 <!--        虹软-->
        <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>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 加入下面这一行 -->
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
                <version>2.3.4.RELEASE</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

配置类初始化

@Data
@Configuration
@ConfigurationProperties(prefix = "arcsoft")
public class ArcSoftConfig {

	private String appid;
	// win平台sdk 此处为了开发时调试 生产一般linux 不需要此设置
	private String winsdkkey;
	// linux平台sdk 
	private String linuxsdkkey;
	// dll/so库路径
	private String libpath;

	/**
	 * 装载FaceEngine交给spring托管
	 * 
	 * @return
	 */
	@Bean
	public FaceEngine faceEngine() {
		String sdkkey = "";
		String os = System.getProperty("os.name");
		if (os.toLowerCase().startsWith("win")) {
			sdkkey = winsdkkey;
			String projectPath = System.getProperty("user.dir");
			libpath = projectPath + "\\libs\\WIN64";
		} else {
			sdkkey = linuxsdkkey;
		}
		FaceEngine faceEngine = new FaceEngine(libpath);
		int errorCode = faceEngine.activeOnline(appid, sdkkey);
		if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
			throw new RuntimeException("引擎注册失败");
		}
		EngineConfiguration engineConfiguration = getFaceEngineConfiguration();
		// 初始化引擎
		errorCode = faceEngine.init(engineConfiguration);
		if (errorCode != ErrorInfo.MOK.getValue()) {
			throw new RuntimeException("初始化引擎失败");
		}
		return faceEngine;
	}

	/**
	 * 初始化引擎配置
	 * 
	 * @return
	 */
	private EngineConfiguration getFaceEngineConfiguration() {
		EngineConfiguration engineConfiguration = new EngineConfiguration();
		// 配置引擎模式
		if ("IMAGE".equals(EngineConfigurationProperty.DETECT_MODE)) {
			engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
		} else {
			engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_VIDEO);
		}
		// 配置人脸角度 全角度 ASF_OP_ALL_OUT 不够准确且检测速度慢
		switch (EngineConfigurationProperty.DETECT_FACE_ORIENT_PRIORITY) {
		case "ASF_OP_0_ONLY":
			engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
			break;
		case "ASF_OP_90_ONLY":
			engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_90_ONLY);
			break;
		case "ASF_OP_270_ONLY":
			engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_270_ONLY);
			break;
		case "ASF_OP_180_ONLY":
			engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_180_ONLY);
			break;
		case "ASF_OP_ALL_OUT":
			engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
			break;
		default:
			engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
		}
		// 设置识别的最小人脸比
		engineConfiguration.setDetectFaceScaleVal(EngineConfigurationProperty.DETECT_FACE_SCALE);
		engineConfiguration.setDetectFaceMaxNum(EngineConfigurationProperty.DETECT_FACE_MAX_NUM);
		// 功能配置
		initFuncConfiguration(engineConfiguration);
		return engineConfiguration;
	}

	/**
	 * 功能配置
	 * 
	 * @param engineConfiguration
	 */
	private void initFuncConfiguration(EngineConfiguration engineConfiguration) {
		FunctionConfiguration functionConfiguration = new FunctionConfiguration();
		// 是否支持年龄检测
		functionConfiguration.setSupportAge(FunConfigurationProperty.SUPPORT_AGE);
		// 是否支持3d 检测
		functionConfiguration.setSupportFace3dAngle(FunConfigurationProperty.SUPPORT_FACE_3D_ANGLE);
		// 是否支持人脸检测
		functionConfiguration.setSupportFaceDetect(FunConfigurationProperty.SUPPORT_FACE_DETECT);
		// 是否支持人脸识别
		functionConfiguration.setSupportFaceRecognition(FunConfigurationProperty.SUPPORT_FACE_RECOGNITION);
		// 是否支持性别检测
		functionConfiguration.setSupportGender(FunConfigurationProperty.SUPPORT_GENDER);
		// 是否支持活体检测
		functionConfiguration.setSupportLiveness(FunConfigurationProperty.SUPPORT_LIVENESS);
		// 是否支持IR活体检测
		functionConfiguration.setSupportIRLiveness(FunConfigurationProperty.SUPPORT_IR_LIVENESS);
		engineConfiguration.setFunctionConfiguration(functionConfiguration);
	}
}

yml配置文件
在这里插入图片描述

其他配置

引擎类

public class EngineConfigurationProperty {

	/**
	 * 引擎模式
	 */
	public static final String DETECT_MODE = "IMAGE";

	/**
	 * 配置人脸角度
	 */
	public static final String DETECT_FACE_ORIENT_PRIORITY = "ASF_OP_ALL_OUT";

	/**
	 * 设置识别的最小人脸比
	 */
	public static final Integer DETECT_FACE_SCALE = 32;

	/**
	 * 最大检测人脸数
	 */
	public static final Integer DETECT_FACE_MAX_NUM = 8;
}

功能类

public class FunConfigurationProperty {

	/**
	 * 是否支持3d 检测
	 */
	public static final Boolean SUPPORT_FACE_3D_ANGLE = true;

	/**
	 * 是否支持人脸检测
	 */
	public static final Boolean SUPPORT_FACE_DETECT = true;

	/**
	 * 是否支持人脸识别
	 */
	public static final Boolean SUPPORT_FACE_RECOGNITION = true;

	/**
	 * 性别检测
	 */
	public static final Boolean SUPPORT_GENDER = true;

	/**
	 * 年龄检测
	 */
	public static final Boolean SUPPORT_AGE = true;

	/**
	 * 是否支持活体检测
	 */
	public static final Boolean SUPPORT_LIVENESS = true;

	/**
	 * 是否至此IR活体检测
	 */
	public static final Boolean SUPPORT_IR_LIVENESS = true;
}

人脸相关方法

@Component
public class ArcFaceMothodUtils {

	@Autowired
	private FaceEngine faceEngine;

	/**
	 * 人脸检测
	 */
	public List<FaceInfo> detectFace(ImageInfoEx imageInfoEx) {
		if (imageInfoEx == null) {
			return null;
		}
		List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
		int i = faceEngine.detectFaces(imageInfoEx, DetectModel.ASF_DETECT_MODEL_RGB, faceInfoList);
		checkEngineResult(i, ErrorInfo.MOK.getValue(), "人脸检测失败");
		return faceInfoList;
	}

	/**
	 * 特征提取
	 */
	public FaceFeature extractFaceFeature(List<FaceInfo> faceInfoList, ImageInfoEx imageInfoEx) {

		if (faceInfoList == null || imageInfoEx == null) {
			return null;
		}
		FaceFeature faceFeature = new FaceFeature();
		int i = faceEngine.extractFaceFeature(imageInfoEx, faceInfoList.get(0), faceFeature);
		checkEngineResult(i, ErrorInfo.MOK.getValue(), "人脸特征提取失败");
		return faceFeature;
	}

	/**
	 * 特征比对
	 */
	public FaceSimilar compareFaceFeature(FaceFeature target, FaceFeature source, CompareModel compareModel) {
		FaceSimilar faceSimilar = new FaceSimilar();
		int i = faceEngine.compareFaceFeature(target, source, compareModel, faceSimilar);
		checkEngineResult(i, ErrorInfo.MOK.getValue(), "人脸特征对比失败");
		return faceSimilar;
	}

	/**
	 * 错误检测
	 */
	private void checkEngineResult(int errorCode, int sourceCode, String errMsg) {
		if (errorCode != sourceCode) {
			throw new RuntimeException(errMsg);
		}

	}
}

虹软图片处理工具类

@Slf4j
public class ArcfaceUtils {

	/**
	 * 处理 File 的图片流
	 * 
	 * @param img
	 * @return
	 */
	public static ImageInfoMeta packImageInfoEx(File img) {
		ImageInfo imageInfo = ImageFactory.getRGBData(img);
		return packImageInfoMeta(imageInfo);
	}

	/**
	 * 处理 byte[] 的图片流
	 * 
	 * @param img
	 * @return
	 */
	public static ImageInfoMeta packImageInfoMeta(byte[] img) {
		ImageInfo imageInfo = ImageFactory.getRGBData(img);
		return packImageInfoMeta(imageInfo);
	}

	/**
	 * 处理 InpuStream 的图片流
	 * 
	 * @param img
	 * @return
	 */
	public static ImageInfoMeta packImageInfoMeta(InputStream img) {
		ImageInfo imageInfo = ImageFactory.getRGBData(img);
		return packImageInfoMeta(imageInfo);
	}

	/**
	 * 处理 网络图片 的图片流
	 *
	 * @param path
	 * @return
	 */
	public static ImageInfoMeta packImageInfoURL(String path) {
		try {
			InputStream inputStream = getImageInputStream(path);
			ImageInfo imageInfo = ImageFactory.getRGBData(inputStream);
			return packImageInfoMeta(imageInfo);
		} catch (Exception e) {
			log.error("处理网络图片处理失败", e);
		}
		return null;
	}

	/**
	 * 处理 base图片 的图片流
	 *
	 * @param base64
	 * @return
	 */
	public static ImageInfoMeta packImageInfoBase64(String base64) {
		try {
			ImageInfo imageInfo = ImageFactory.getRGBData(removeBase64Prefix(base64));
			return packImageInfoMeta(imageInfo);
		} catch (Exception e) {
			log.error("处理网络图片处理失败", e);
		}
		return null;
	}

	public static byte[] removeBase64Prefix(String base64String) {
		if (base64String.startsWith("data:image/jpeg;base64,")) {
			base64String = base64String.replace("data:image/jpeg;base64,", "");
		}
		if (base64String.startsWith("data:image/png;base64,")) {
			base64String = base64String.replace("data:image/png;base64,", "");
		}
		return Base64.getDecoder().decode(base64String);
	}

	public static InputStream getImageInputStream(String imageUrl) throws Exception {
		URL url = new URL(imageUrl);
		URLConnection connection = url.openConnection();
		return connection.getInputStream();
	}

	/**
	 * 打包生成 ImageInfoMeta
	 * 
	 * @param imageInfo
	 * @return
	 */
	private static ImageInfoMeta packImageInfoMeta(ImageInfo imageInfo) {
		ImageInfoMeta imageInfoMeta = new ImageInfoMeta(imageInfo);
		return imageInfoMeta;
	}

	/**
	 * 对imageInfo 和 imageInfoEx 的打包对象
	 * 
	 * @return
	 */
	@Data
	public static class ImageInfoMeta {
		private ImageInfo imageInfo;
		private ImageInfoEx imageInfoEx;

		public ImageInfoMeta(ImageInfo imageInfo) {
			this.imageInfo = imageInfo;
			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 });
		}
	}

}

实际业务使用

        // 开始使用虹软人脸识别
		ArcfaceUtils.ImageInfoMeta imageInfoMeta1 = ArcfaceUtils.packImageInfoURL(photo);
		if (null == imageInfoMeta1) {
			throw new ValidatorException("您的人脸信息在系统内已失效请重新录入");
		}
		// 系统的人脸库信息
		List<FaceInfo> faceInfo1 = arcFaceMothodUtils.detectFace(imageInfoMeta1.getImageInfoEx());
		FaceFeature faceFeature1 = arcFaceMothodUtils.extractFaceFeature(faceInfo1, imageInfoMeta1.getImageInfoEx());

		// 当前需要对比的人脸
		ArcfaceUtils.ImageInfoMeta imageInfoMeta2 = ArcfaceUtils.packImageInfoBase64(dto.getFacePic());
		if (null == imageInfoMeta2) {
			throw new ValidatorException("您的人脸信息人脸特征提取失败,请重试");
		}
		List<FaceInfo> faceInfo2 = arcFaceMothodUtils.detectFace(imageInfoMeta2.getImageInfoEx());
		FaceFeature faceFeature2 = arcFaceMothodUtils.extractFaceFeature(faceInfo2, imageInfoMeta2.getImageInfoEx());
		FaceSimilar faceSimilar = arcFaceMothodUtils.compareFaceFeature(faceFeature1, faceFeature2,
				CompareModel.LIFE_PHOTO);
		// 相似度
		float score = faceSimilar.getScore();
		log.info("当前匹配的身份证信息【{}】,相似度:{}", dto.getUserId(), score);

希望对大家能够有所帮助 仅作为个人笔记使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/306580.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | 主干篇 | 12月最新成果UniRepLknet特征提取网络(附对比试验效果图)

一、本文介绍 本文给大家带来的改进机制是特征提取网络UniRepLknet,其也是发表于今年12月份的最新特征提取网络,该网络结构的重点在于使用Dilated Reparam Block和大核心指导原则,强调了高效的结构进行通道间通讯和空间聚合,以及使用带扩张的小核心进行重新参数化,该网络…

日志系统一(elasticsearch+filebeat+logstash+kibana)

目录 一、es集群部署 安装java环境 部署es集群 安装IK分词器插件 二、filebeat安装&#xff08;docker方式&#xff09; 三、logstash部署 四、kibana部署 背景&#xff1a;因业务需求需要将nginx、java、ingress日志进行收集。 架构&#xff1a;filebeatlogstasheskib…

java继承Thread实现多线程

1、AdminController文件 package com.controller;import com.myThread.AdminThread; import org.springframework.web.bind.annotation.*;RestController CrossOrigin RequestMapping("/admin") public class AdminController{GetMapping("/{id}")public …

基于Github官方教程的快速入门学习

GitHub 是一个用于版本控制和协作的代码托管平台。 它允许您和其他人随时随地协同处理项目。 创建仓库 在任何页面的右上角&#xff0c;使用 下拉菜单选择“新建存储库”。 之后会进入创建仓库的界面&#xff0c;需要我们进行如下操作&#xff1a; 写仓库的名字写对于本仓库…

Uibot (RPA设计软件)微信群发助手机器人————课前材料二

(本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; 紧接着小北的前两篇博客&#xff0c;友友们我们即将开展新课的学习~RPA 培训前期准备指南——安装Uibot(RPA设计软件&#xff09;-CSDN博客https://blog.csdn.net/Zhiyilang/article/details/1…

现代操作系统复习笔记【核心考点知识+重点复习题】

文章目录 一、核心考点基础知识第一章 概述1、操作系统的基本概念、基本功能2、分时系统、批处理系统、实时系统的主要特征3、用户接口、系统调用过程4、单到与多道程序技术5、操作系统虚拟机体系结构6、CPU工作模式&#xff1b;7、部分课后习题 第二章 进程与线程1、进程的基本…

华为 HarmonyOS 页面跳转

1. 我们新建2个页面(page)&#xff0c;一个Hello World页面&#xff0c;一个Hello HarmonyOS页面&#xff0c;注意修改红色框内容&#xff0c;保持一致 2.导入导入router模块&#xff0c;页面跳转接口&#xff0c;添加按钮点击事件 //导入router模块 页面跳转接口 import rout…

Matlab绘制双纵轴图(yyaxis函数)

一、方法一yyaxis函数 x linspace(0,pi); y1 cos(x); yyaxis left; % 激活左边的轴 plot(x,y1) xlabel(X-axis); ylabel(left Y-axis); % 给左y轴添加轴标签hold on yyaxis right; % 激活右边的轴 y2 cos(2*x); plot(x,y2) ylim([-1,1]); % 设置右y轴的界限 ylabel(right Y…

打PTA 分数 15

传说这是集美大学的学生对话。本题要求你做一个简单的自动问答机&#xff0c;对任何一个问句&#xff0c;只要其中包含 PTA 就回答 Yes!&#xff0c;其他一概回答 No.。 输入格式&#xff1a; 输入第一行给出一个整型范围内的正整数 N&#xff0c;随后 N 行&#xff0c;每行给…

动态规划python简单例子-斐波那契数列

def fibonacci(n):dp [0, 1] [0] * (n - 1) # 初始化动态规划数组for i in range(2, n 1):dp[i] dp[i - 1] dp[i - 2] # 计算斐波那契数列的第 i 项print(dp)return dp[n] # 返回斐波那契数列的第 n 项# 示例用法 n 10 # 计算斐波那契数列的第 10 项 result fibonac…

无法找到 WindowsKernelModeDriver10.0 的生成工具

无法找到 WindowsKernelModeDriver10.0 的生成工具(平台工具集 “WindowsKernelModeDriver10.0”)。若要使用 WindowsKernelModeDriver10.0 生成工具进行生成&#xff0c;请安装 WindowsKernelModeDriver10.0 生成工具。或者&#xff0c;可以升级到当前 Visual Studio 工具&…

源码|redis7.2.2|sds

文章目录 前言Type && EncodingsdsencodingcreateStringObjectcreateEmbeddedStringObject总结 createRawStringObject总结 createStringObjectFromLongDouble总结 createStringObjectFromLongLongWithOptions总结 相关操作sdscatlen总结 阈值44sds VS C字符串 前言 从…

HTTP 3xx状态码:重定向的场景与区别

HTTP 状态码是服务器响应请求时传递给客户端的重要信息。3xx 系列的状态码主要与重定向有关&#xff0c;用于指示请求的资源已被移动到不同的位置&#xff0c;需要采取不同的操作来访问。 一、301 Moved Permanently 定义&#xff1a; 服务器表明请求的资源已永久移动到一个新…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)在TcpConnection 中接收并解析Http请求消息

一、在TcpConnection 中多添加和http协议相关的request和response struct TcpConnection {struct EventLoop* evLoop;struct Channel* channel;struct Buffer* readBuf;struct Buffer* writeBuf;char name[32];// http协议struct HttpRequest* request;struct HttpResponse* r…

Phoenix基本使用

1、Phoenix简介 1.1 Phoenix定义 Phoenix是HBase的开源SQL皮肤。可以使用标准JDBC API代替HBase客户端API来创建表&#xff0c;插入数据和查询HBase数据。 1.2 Phoenix特点 容易集成&#xff1a;如Spark&#xff0c;Hive&#xff0c;Pig&#xff0c;Flume和Map Reduce。性能…

Python处理字符串-正则提取遇到的第一个完整括号内容处理后替换

1.场景分析 该场景介绍如何用python语言&#xff0c;使用正则表达式处理字符串内第一个完整的括号内容&#xff0c;一个括号内可能会含有一个括号&#xff0c;多个括号自行扩展正则即可&#xff0c;处理完成后再替换到括号的内容 2.重难点 第一个括号内可能会还有另一个括号 …

Poi实现根据word模板导出-图表篇

往期系列传送门&#xff1a; Poi实现根据word模板导出-文本段落篇 &#xff08;需要完整代码的直接看最后位置&#xff01;&#xff01;&#xff01;&#xff09; 前言&#xff1a; 补充Word中图表的知识&#xff1a; 每个图表在word中都有一个内置的Excel&#xff0c;用于…

云原生Kubernetes: Kubeadm部署K8S 1.29版本 单Master架构

目录 一、实验 1.环境 2.K8S master节点环境准备 3.K8S master节点安装kubelet、kubeadm、kubectl 3.K8S node节点环境准备与软件安装 4.K8S master节点部署服务 5.K8S node节点部署 6.K8S master节点查看集群 7.容器网络&#xff08;CNI&#xff09;部署 8.K8S 集群…

使用Excel批量给数据添加单引号和逗号

表格制作过程如下&#xff1a; A2表格暂时为空&#xff0c;模板建立完成以后&#xff0c;用来放置原始数据&#xff1b; 在B2表格内输入公式&#xff1a; ""&A2&""&"," 敲击回车&#xff1b; 解释&#xff1a; B2表格的公式&q…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷③

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷3 目录 需要竞赛软件包环境以及备赛资源可私信博主&#xff01;&#xff01;&#xff01; 2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷3 模块一 …