虹软人脸识别初试(windows SDK,idea,USB摄像头)

  • 简介
  • 准备库
    • 注册账号
    • 下载SDK
    • 库结构
  • 建项目
    • 添加javacv依赖
    • 添加虹软依赖
    • 激活人脸库
    • 提取特征
    • 主程序
  • 参考

简介

现在人脸识别技术应用越来越广泛,对于个人来说,最大的障碍是模型训练太难,合理利用现成的库可以大大加速开发速度。虹软的库效果不错,并且免费试用,值得一试。本文就利用虹软的库做一个简单的人脸识别程序,仅仅是为了跑通。

准备库

注册账号

到虹软视觉官网,点击右上角 开发者中心 ,进行账号注册和登录。

下载SDK

进入 我的应用

点击右上角 添加SDK 按钮,根据自身需要选择对应的SDK,获得SDK_KEY并且下载SDK。本次下载的SDK是

库结构


建议先看下 开发说明文档,不看也没关系,反正几个函数,以后用到再翻也可以。

建项目

由于这个项目后继还有别的用途,所以建成springboot项目,并且添加了mysql,web,mybatis,log4j等,如果单纯为这个试验建项目,可以建个maven项目。

添加javacv依赖

pom文件加上依赖:

        <!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform --><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.7</version></dependency>

这个库很大,建议改阿里源进行下载。

添加虹软依赖

在资源文件夹创建一个lib文件夹,将虹软的java依赖库复制进去

pom文件加上依赖

        <dependency><groupId>com.arcsoft.face</groupId><artifactId>arcsoft-sdk-face</artifactId><version>3.0.0.0</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/arcsoft-sdk-face-3.0.0.0.jar</systemPath></dependency>

maven刷新一下

激活人脸库

创建一个类来激活库
注意更改appId, sdkKey, lib路径

public class ActiveEng {private static final Logger logger = Logger.getLogger(Javacv.class);public static void main(String[] args) {//从官网获取String appId = "";//在账号下面找String sdkKey = "";//在账号里面找FaceEngine faceEngine = new FaceEngine("F:\\arcsoft_lib");//sdk lib的位置//激活引擎int errorCode = faceEngine.activeOnline(appId, sdkKey);if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {logger.debug("引擎激活失败");}else {logger.debug("引擎激活成功");}}
}

激活以后会在项目文件夹下生产一个ArcFace64.dat文件

提取特征

在做1:N之前,要将人脸信息的特征提取出来,保存好,方便以后比对
在项目文件夹里面建两个文件夹:record和feature,把模板照片放到record里面,创建一个类提取特征。

public class SaveFaceFeature {private static final Logger logger = Logger.getLogger(Javacv.class);public static void main(String[] args) {//识别库初始化FaceEngine faceEngine = new FaceEngine("F:\\arcsoft_lib");//激活信息ActiveFileInfo activeFileInfo=new ActiveFileInfo();int errorCode = faceEngine.getActiveFileInfo(activeFileInfo);if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {logger.debug("获取激活文件信息失败,返回代码:" + errorCode);} else {logger.debug("获取激活文件信息成功,返回代码:" + errorCode);}//引擎配置EngineConfiguration engineConfiguration = new EngineConfiguration();engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);//图像模式engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY); //逆时针0度engineConfiguration.setDetectFaceMaxNum(1);engineConfiguration.setDetectFaceScaleVal(32);//功能配置FunctionConfiguration functionConfiguration = new FunctionConfiguration();//functionConfiguration.setSupportAge(true); //年龄检测//functionConfiguration.setSupportFace3dAngle(true); //3D角度检测functionConfiguration.setSupportFaceDetect(true); //人脸检测functionConfiguration.setSupportFaceRecognition(true); //人脸识别//functionConfiguration.setSupportGender(true); //性别检测functionConfiguration.setSupportLiveness(true); //活体检测//functionConfiguration.setSupportIRLiveness(true); //红外活体检测engineConfiguration.setFunctionConfiguration(functionConfiguration);//初始化引擎errorCode = faceEngine.init(engineConfiguration);if (errorCode != ErrorInfo.MOK.getValue()) {logger.debug("初始化引擎失败" + errorCode);}//获取目录的路径//使用相对路径//换成绝对路径//显示出来//把record文件里面的图片抽取特征,按身份证号存在feature文件夹里面String recordPath = "./record"; // 模板目录路径String featurePath = "./feature"; // 特征目录路径File recordDocument = new File(recordPath);//获取路径//模板路径的目录不存在的话直接跳出if (!recordDocument.exists()) {logger.debug("模板图像目录" + recordPath + "不存在");//不存在就输出return;}File fa[] = recordDocument.listFiles();//用数组接收//没有文件直接跳出if(fa.length == 0){logger.debug("目录里面没有图片");}List<FaceInfo> faceInfoList = new ArrayList<>();ImageInfo imageInfo = new ImageInfo();ImageInfoEx imageInfoEx = new ImageInfoEx();FaceFeature feature = new FaceFeature();//逐一提取特征并且保存for (File record:fa) {logger.debug("提取" + record.toString() + "的特征");//imageInfoEx需要imageInfoimageInfo = getRGBData(record);//extractFaceFeature(byte[] data, int width, int height, ImageFormat imageFormat,// FaceInfo faceInfo, FaceFeature feature)//extractFaceFeature(ImageInfoEx imageInfoEx, FaceInfo faceInfo, FaceFeature feature)//extractFaceFeature(byte[][] imageDataPlanes, int[] imageStrides, int width, int height,// ImageFormat imageFormat, FaceInfo faceInfo, FaceFeature feature)//三种方法可以提取特征//我们选择第二种,需要ImageInfoEx和FaceInfo//ImageInfoEximageInfoEx.setHeight(imageInfo.getHeight());imageInfoEx.setWidth(imageInfo.getWidth());imageInfoEx.setImageFormat(imageInfo.getImageFormat());imageInfoEx.setImageDataPlanes(new byte[][]{imageInfo.getImageData()});imageInfoEx.setImageStrides(new int[]{imageInfo.getWidth() * 3});errorCode = faceEngine.detectFaces(imageInfoEx, DetectModel.ASF_DETECT_MODEL_RGB, faceInfoList);//提取featureerrorCode = faceEngine.extractFaceFeature(imageInfoEx, faceInfoList.get(0), feature);//保存特征String featureFileName =featurePath + "/" +record.getName().substring(0, 18) + ".dat";File featureFile = new File(featureFileName);try {OutputStream outputStream = new FileOutputStream(featureFile);outputStream.write(feature.getFeatureData());outputStream.flush();outputStream.close();} catch (FileNotFoundException e) {logger.debug("创建输出流失败" + featureFileName);e.printStackTrace();} catch (IOException e) {logger.debug("文件写入失败" + featureFileName);e.printStackTrace();}logger.debug(featureFileName);}//引擎卸载errorCode = faceEngine.unInit();}
}

运行提取模板图像的特征,保存到feature文件夹备用

主程序

创建一个实体类

public class RegistedFeatureInfo {private String idNum;private FaceFeature faceFeature;public String getIdNum() {return idNum;}public void setIdNum(String idNum) {this.idNum = idNum;}public FaceFeature getFaceFeature() {return faceFeature;}public void setFaceFeature(FaceFeature faceFeature) {this.faceFeature = faceFeature;}@Overridepublic String toString() {return "RegistedFeatureInfo{" +"idNum='" + idNum + '\'' +", faceFeature=" + faceFeature +'}';}
}

主类
基本就是把特征读入list,javacv开窗抓frame,找人头提特征,逐个对比,过阈值显示出来。
javacv部分可以参考 eguid_1 大神的各个专栏,不要吝惜一百几十块钱。

public class Javacv {private static final Logger logger = Logger.getLogger(Javacv.class);public void openCam() throws FrameGrabber.Exception {FaceEngine faceEngine = new FaceEngine("F:\\arcsoft_lib");ActiveFileInfo activeFileInfo=new ActiveFileInfo();AtomicInteger errorCode = new AtomicInteger(faceEngine.getActiveFileInfo(activeFileInfo));if (errorCode.get() != ErrorInfo.MOK.getValue() && errorCode.get() != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {logger.debug("获取激活文件信息失败,返回代码:" + errorCode);} else {logger.debug("获取激活文件信息成功,返回代码:" + errorCode);}//引擎配置EngineConfiguration engineConfiguration = new EngineConfiguration();engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);//图像模式engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY); //逆时针0度engineConfiguration.setDetectFaceMaxNum(1);engineConfiguration.setDetectFaceScaleVal(32);//功能配置FunctionConfiguration functionConfiguration = new FunctionConfiguration();//functionConfiguration.setSupportAge(true); //年龄检测//functionConfiguration.setSupportFace3dAngle(true); //3D角度检测functionConfiguration.setSupportFaceDetect(true); //人脸检测functionConfiguration.setSupportFaceRecognition(true); //人脸识别//functionConfiguration.setSupportGender(true); //性别检测functionConfiguration.setSupportLiveness(true); //活体检测//functionConfiguration.setSupportIRLiveness(true); //红外活体检测engineConfiguration.setFunctionConfiguration(functionConfiguration);//初始化引擎errorCode.set(faceEngine.init(engineConfiguration));if (errorCode.get() != ErrorInfo.MOK.getValue()) {logger.debug("初始化引擎失败" + errorCode);}OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);//新建opencv抓取器,一般的电脑和移动端设备中摄像头默认序号是0,不排除其他情况grabber.start();//开始获取摄像头数据CanvasFrame canvas = new CanvasFrame("摄像头预览");//新建一个预览窗口canvas.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//grabber抓的是fram//faceEngine.detectFaces 要用到 imageInfo//imageInfo要通过getRGBData获得//getRGBData(byte[] bytes) getRGBData(InputStream input)//byte[] 或者 InputStream 格式的数据都可以用//grabber抓的是frame//如何将frame转化为 byte[]或者 InputStream//目前只能frame转BufferedImage转 byte[]Frame frame = new Frame();List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();ImageInfo imageInfo = new ImageInfo();ByteArrayOutputStream bStream = new ByteArrayOutputStream();int countTimes = 0;OpenCVFrameConverter converter = new OpenCVFrameConverter.ToMat();boolean faceDetected = false;Point pointA = new Point();Point pointB = new Point();//创建feature的listList<RegistedFeatureInfo> rfiList = new ArrayList<>();//读取feature文件夹里面的数据,写入list里面//文件夹位置String featurePath = "./feature"; // 特征目录路径File featureDocument = new File(featurePath);//获取路径//模板路径的目录不存在的话直接跳出if (!featureDocument.exists()) {logger.debug("人员特征目录" + featurePath + "不存在");//不存在就输出return;}File fa[] = featureDocument.listFiles();//用数组接收//没有文件直接跳出if(fa.length == 0){logger.debug("没有特征数据");}//读取//isfor (File feature:fa) {try {//创建输入流InputStream inputStream = new FileInputStream(feature.getAbsoluteFile());//创建特征RegistedFeatureInfo registedFeatureInfo = new RegistedFeatureInfo();FaceFeature faceFeature = new FaceFeature();//创建缓存byte[] bytes = new byte[faceFeature.FEATURE_SIZE];//读数据进缓存inputStream.read(bytes);//写数据进特征faceFeature.setFeatureData(bytes);registedFeatureInfo.setFaceFeature(faceFeature);registedFeatureInfo.setIdNum(feature.getName().substring(0, 18));//添加到list里面rfiList.add(registedFeatureInfo);//关闭isinputStream.close();logger.debug("现有" + rfiList.size() + "人在库");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}//窗口是否关闭while(canvas.isDisplayable()){/*获取摄像头图像并在窗口中显示,这里Frame frame=grabber.grab()得到是解码后的视频图像*/frame = grabber.grab();countTimes++;if(countTimes % 10 == 0){BufferedImage bufferedImage = Java2DFrameUtils.toBufferedImage(frame);try {ImageIO.write(bufferedImage, "jpg", bStream);} catch (IOException e) {e.printStackTrace();}imageInfo = getRGBData(bStream.toByteArray());bStream.reset();/*logger.debug("图片格式:\n" + "高" + imageInfo.getHeight()+ "   宽" + imageInfo.getWidth()+ "   图片格式" + imageInfo.getImageFormat().toString());
*/errorCode.set(faceEngine.detectFaces(imageInfo.getImageData(),imageInfo.getWidth(),imageInfo.getHeight(),imageInfo.getImageFormat(),faceInfoList));if(faceInfoList.size() > 0){//logger.debug(faceInfoList.get(0).getRect());//更新矩形的信息pointA.x(faceInfoList.get(0).getRect().getLeft());pointA.y(faceInfoList.get(0).getRect().getTop());pointB.x(faceInfoList.get(0).getRect().getRight());pointB.y(faceInfoList.get(0).getRect().getBottom());if(pointB.x()-pointA.x() > 150){faceDetected = true;//提取这个人的特征//特征提取2FaceFeature faceFeature2 = new FaceFeature();faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(),imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature2);//看看这个人是谁FaceSimilar faceSimilar = new FaceSimilar();Float fSimilar = 0.0F;String idNumR = "";for (RegistedFeatureInfo person:rfiList) {//对比faceEngine.compareFaceFeature(faceFeature2, person.getFaceFeature(), faceSimilar);//如果faceSimilar大于存储值,更新if(faceSimilar.getScore() > fSimilar){fSimilar = faceSimilar.getScore();idNumR = person.getIdNum();}}if(fSimilar > 0.8F){logger.debug("人员对比最高值为" + fSimilar.toString() + ";id为" + idNumR);}}else{faceDetected = false;}} else {faceDetected = false;}}//如果有头像if(faceDetected){//将frame转换成matMat mat = Java2DFrameUtils.toMat(frame);//加上方框//rectangle(grabbedImage, new Point(x, y), new Point(x + w, y + h), Scalar.RED, 1, CV_AA, 0);rectangle(mat, pointA, pointB, Scalar.GREEN, 5, CV_AA, 0);//mat转换成frameframe = converter.convert(mat);}canvas.showImage(frame);try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}grabber.close();//停止抓取}
}

springboot缺省使用headless模式,要禁用,否则会报awt异常

public class RlsbjApplication {public static void main(String[] args) {//springboot缺省用headless模式启动,要禁用这种模式,否则会报错SpringApplicationBuilder builder = new SpringApplicationBuilder(RlsbjApplication.class);builder.headless(false).run(args);//SpringApplication.run(RlsbjApplication.class, args);Javacv javacv = new Javacv();try {javacv.openCam();} catch (FrameGrabber.Exception e) {e.printStackTrace();}}}

运行效果

参考

参考1:https://blog.csdn.net/eguid_1/article/details/51659578

虹软人脸识别初试(windows SDK,idea,USB摄像头)相关推荐

  1. 基于虹软人脸识别-iOS画框更改及前后摄像头的切换

    公司项目使用过程中,为了配合市场需要,需要增加人脸识别+活体检测的功能.并且要求人脸识别的样式接近于主流产品的样式.所以选择了方便快捷的虹软人脸识别SDK. 1.项目逻辑流程图 根据下面的逻辑梳理,可 ...

  2. Android开发之虹软人脸识别活体检测SDK包Bitmap转NV21方法

    /** * Bitmap 转化为 ARGB 数据,再转化为 NV21 数据 * * @param src 传入的 Bitmap,格式为 Bitmap.Config.ARGB_8888 * @param ...

  3. android bitmap nv21,Android开发之虹软人脸识别活体检测SDK包Bitmap转NV21方法

    /** * Bitmap 转化为 ARGB 数据,再转化为 NV21 数据 * * @param src 传入的 Bitmap,格式为 Bitmap.Config.ARGB_8888 * @param ...

  4. 虹软人脸识别 SDK 使用 Unity Android C# Java多语言开发 2021-09-06

    Unity接入虹软人脸识别Android版SDK == 自改aar包开发Android应用 下方有下载链接所有 demo aar 包== 文章目录 Unity接入虹软人脸识别Android版SDK 简 ...

  5. unity接入实现人脸识别应用-基于虹软人脸识别算法4.0

    一.准备工作 1.下载虹软人脸识别增值版SDK 4.0 1)注册并登录开发者中心 2)下载虹软人脸识别SDK 2.安装Unity3D及Visual Studio 2019开发环境 1)安装Unity ...

  6. 虹软java接摄像头_虹软人脸识别SDK(java+linux/window) 初试

    虹软人脸识别全平台demo调用-快速上手之服务端Windows篇 demo名称:ArcFace 2.2 Windows(86) Demo [C++] 一 环境配置: 1) 安装VS2013环境安装包( ...

  7. 虹软人脸识别SDK接入Milvus实现海量人脸快速检索

    虹软人脸识别SDK接入Milvus实现海量人脸快速检索 背景 虹软SDK及Milvus简介 开发环境 虹软人脸识别SDK使用简介 Milvus环境搭建 快速检索实现 人脸识别流程简介 快速检索 虹软S ...

  8. 虹软人脸识别SDK的使用

    虹软人脸识别SDK使用说明 使用虹软平台需要先注册开发者账号: https://ai.arcsoft.com.cn/ucenter/user/userlogin 注册完成后进行登录,然后进行创建应用: ...

  9. SpringBoot 基于向量搜索引擎及虹软人脸识别SDK的大规模人脸搜索

    SpringBoot 基于向量搜索引擎及虹软人脸识别SDK的大规模向量数据搜索 文章目录 SpringBoot 基于向量搜索引擎及虹软人脸识别SDK的大规模向量数据搜索 在线环境demo 在线环境说明 ...

最新文章

  1. keepalived and heartbeat
  2. tensorflow 中报错ValueError: Found input variables with inconsistent numbers of samples: [5492, 14280]
  3. GML-SVG-VML比较
  4. 成功解决File frozen importlib._bootstrap, line 219, in _call_with_frames_removed ImportError: DLL lo
  5. jQuery Ajax 实例
  6. C语言试题四十六之将m行n列的二维数组中的字符数据,按列的顺序依次放到一个字符串中。
  7. centos8启动zk集群失败:zk Error contacting service. It is probably not running.
  8. mybatis动态更新xml文件后热部署,不重启应用的方法
  9. 英语口语-文章朗读Week9 TuesDay
  10. Swift 面向协议编程的那些事
  11. Knockout获取数组元素索引的2种方法,在MVC中实现
  12. innerHTML、outerHTML、innerText、outerText的区别及兼容性问题
  13. 只腐蚀毛刺 腐蚀算法_工件刺虽小,去除却难!介绍几种先进去毛刺工艺,操作简单实用...
  14. 深入浅出mysql数据开发_深入浅出MySQL数据库开发、优化与管理维护 PDF扫描版[513KB]...
  15. 后台数据联调的接口工具 postman和apizza 集成数据
  16. 电容触摸按键实验(STM32F407)
  17. 百度Uditor富文本编辑器使用以及图片不显示问题
  18. python下载电影天堂视频_Python抓取电影天堂电影信息的代码
  19. oppo小布机器人_看这一篇就够了,1分钟带你了解OPPO小布的隐藏玩法!
  20. POI生成Word水印watermark(兼容WPS)的终极解决方案

热门文章

  1. 国内外目前比较流行的CMS大全(持续更新~)
  2. jupyter快捷键使用
  3. html multipart/form-data,深刻解析 multipart/form-data
  4. Android 代码精简 -- dimen抽取遇到的坑
  5. c语言用栈编写计算器程序,用c语言实现简易的计算器四则运算的代码最好用栈方法实现,该怎么解决...
  6. #include stdio.h 和#include stdio.h 的区别
  7. STM32中断:NVIC与EXTI
  8. 还是一篇来自Java14th的学习、面试经验分享
  9. 安徽鼓励仿制药研发 全国首仿有重奖
  10. C语言中const用法解析