springboot虹软人脸识别集成

news2024/11/24 15:43:04

准备工作

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

开始上代码

基本配置

在这里插入图片描述
将下载的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.coloradmin.cn/o/1369797.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【RH850U2A芯片】RAM and Flash介绍

目录 前言 正文 1.RH850-U2A16芯片RAM 1.1 用户使用RAM类型及大小 1.2 各类RAM起始地址 1.3 LRAM和CRAM的区别 1.4 RAM初始化问题 1.5 RAM使用经验 2.RH850-U2A16芯片Flash 2.1 Flash类型及大小 2.2 各类Flash的起始地址 2.3 Code Flash和Data Flash的区别 2.4 Fl…

谷粒商城项目|微服务架构的一些与思考解决跨域问题

1.微服务架构的组成每部分的作用 2.还有其他的微服务架构模式吗 3.微服务服务交互的方式 1&#xff09;grpc 2&#xff09;rest api 4.微服务网关与API网关&#xff1f; 5.注册中心比较&#xff08;Nacos与Eureka&#xff09; Nacos Nacos 是阿里巴巴开源的项目&#xff0c;N…

Vue2.v-指令

v-if 在双引号中写判断条件。 <div v-if"score>90">A</div> <div v-else-if"score>80">B</div> <div v-else>C</div>v-on: :冒号后面跟着事件。 为了简化&#xff0c;可以直接用代替v-on:。 事件名“内联语…

Nessus漏洞扫描工具安装、使用技巧及注意事项

Nessus是一款功能强大的安全评估工具&#xff0c;它可以帮助安全团队快速发现网络中潜在的安全风险和漏洞&#xff0c;并对其进行评估和修复。对于渗透测试人员来说&#xff0c;Nessus更是必不可少的工具之一。 1. Nessus安装 获取安装包&#xff0c;官网地址&#xff1a;http…

【数据库】MySQL锁

一、锁的基本概念 1、锁的定义 锁是协调多个进程或线程并发访问数据库资源的一种机制。 MySQL中的锁是在服务器层或者存储引擎层实现的&#xff0c;保证了数据访问的一致性与有效性。但加锁是消耗资源的&#xff0c;锁的各种操作&#xff0c;包括获得锁、检测锁是否已解除、…

26 数字验证

效果演示 实现了一个简单的数字密码输入表单&#xff0c;用户需要输入一个4位数字密码来验证身份。表单包含一个标题、描述、输入字段、两个按钮和一个关闭按钮。输入字段是一个4位数字密码&#xff0c;用户需要在每个输入框中输入数字来输入密码。两个按钮分别是“验证”和“清…

简单的MOV转MP4方法

1.下载腾讯的QQ影音播放器, 此播放器为绿色视频播放器, 除了播放下载好的视频外没有臃肿无用功能 官网 QQ影音 百度网盘链接&#xff1a;https://pan.baidu.com/s/1G0kSC-844FtRfqGnIoMALA 提取码&#xff1a;dh4w 2.用QQ影音打开MOV文件 3.右下角打开影音工具箱 , 选择截取…

【Java并发】聊聊concurrentHashMap的put核心流程

结构介绍 1.8中concurrentHashMap采用数组链表红黑树的方式存储&#xff0c;并且采用CASSYN的方式。在1.7中主要采用的是数组链表&#xff0c;segment分段锁reentrantlock。本篇主要在1.8基础上介绍下. 那么&#xff0c;我们的主要重点是分析什么呢&#xff0c;其实主要就是p…

强化学习在生成式预训练语言模型中的研究现状简单调研

1. 绪论 本文旨在深入探讨强化学习在生成式预训练语言模型中的应用&#xff0c;特别是在对齐优化、提示词优化和经验记忆增强提示词等方面的具体实践。通过对现有研究的综述&#xff0c;我们将揭示强化学习在提高生成式语言模型性能和人类对话交互的关键作用。虽然这些应用展示…

kubernetes volume 数据存储详解

写在前面&#xff1a;如有问题&#xff0c;以你为准&#xff0c; 目前24年应届生&#xff0c;各位大佬轻喷&#xff0c;部分资料与图片来自网络 内容较长&#xff0c;页面右上角目录方便跳转 概述 容器的生命周期可能很短&#xff0c;会被频繁的创建和销毁 保存在容器中的…

Leetcode刷题笔记题解(C++):无重复字符的最长子串

思路&#xff1a; 利用滑动窗口的思想&#xff0c;用起始位置startindex和curlength来记录这个滑动窗口的大小&#xff0c;并且得出最长距离&#xff1b;利用哈希表来判断在滑动窗口中是否存在重复字符&#xff0c;代码如下所示&#xff1a; class Solution { public:int len…

6.1 截图工具HyperSnap6简介

图片是组成多媒体作品的基本元素之一&#xff0c;利用图片可以增强多媒体作品的亲和力和说说服力。截取图片最简单的方法是直接按下键盘上的“PrintScreen”键截取整个屏幕或按下“AltPrintScreen”组合键截取当前活动窗口&#xff0c;然后在画笔或者其它的图片处理软件中进行剪…

基于SSM的在线电影票购买系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的在线电影票购买系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring…

【模拟IC学习笔记】Cascode OTA 设计

辅助定理 增益Gm*输出阻抗 输出短路求Gm 输入置0求输出阻抗 求源极负反馈的增益 随着Vin的增加&#xff0c;Id也在增加&#xff0c;Rs上压降增加&#xff0c;所以&#xff0c;Vin的一部分电压体现在Rs上&#xff0c;而不是全部作为Vgs&#xff0c;因此导致Id变得平滑。 Rs足…

软件测试|MySQL DISTINCT关键字过滤重复数据

简介 在MySQL中&#xff0c;有时候我们需要从表中检索唯一的、不重复的数据。这时&#xff0c;我们可以使用DISTINCT关键字来过滤掉重复的数据行。在本文中&#xff0c;我们将深入探讨MySQL中DISTINCT的用法以及如何在查询中使用它来得到不重复的结果集。 基本语法 DISTINCT…

Influxdb2修改管理员密码

通过恢复管理员令牌来重置InfluxDB2管理员的密码 1.找到数据库的配置文件 一般为config.json 2.配置文件的的blod文件配置 3.在这个混合文本和二进制json文件中搜索已知的用户名或token之类的字符串。 例如&#xff1a; "id":"0bd73badf2941000","…

系列十四、理解MySQL varchar(50)

一、理解MySQL varchar(50) 1.1、概述 日常开发中&#xff0c;数据库建表是必不可少的一个环节&#xff0c;建表的时候通常会看到设定某个字段的长度为varchar(50)&#xff0c;例如如下建表语句&#xff1a; 那么怎么理解varchar(50)&#xff1f;这个分情况的&#xff0c;MySQ…

美创科技葛宏彬:夯实安全基础,对医疗数据风险“逐个击破”

导读 解决医疗机构“临床业务数据合规流动”与“重要数据安全防护”两大难题。 2023年11月11日&#xff0c;在2023年南湖HIT论坛上&#xff0c;HIT专家网联合杭州美创科技股份有限公司&#xff08;以下简称美创科技&#xff09;发布《医疗数据安全风险分析及防范实践》白皮书…

遇到U盘写保护怎么办

U盘写保护 为什么出现写保护的情况 U盘写保护&#xff0c;就是无法对U盘数据进行修改&#xff08;添加、删除、修改名称&#xff09;。 u盘写保护分为硬件写保护、系统或软件异常导致的写保护。 硬件写保护一般是U盘上硬件写保护开关被开启&#xff08;常见于SD卡读卡器侧面会…

【大数据架构】日志采集方案对比

整体架构 日志采集端 Flume Flume的设计宗旨是向Hadoop集群批量导入基于事件的海量数据。系统中最核心的角色是agent&#xff0c;Flume采集系统就是由一个个agent所连接起来形成。每一个agent相当于一个数据传递员&#xff0c;内部有三个组件&#xff1a; source: 采集源&…