ArcSoft3.0_Nodejs

一、项目说明

虹软官网传送门 ,有不同平台和不同版本的sdk,有需要的根据业务下载。
此次项目支持windows和linux系统,mac 由于 禁用electron打包的应用。

  1. 项目由electron-vue脚手架创建。
  2. 在主线程中实现与虹软SDK交互,如果还需要和render层交互,还需使用app.on来接收render层传过来的业务。
  3. vue打包时,需要在package.json中配置包含路径。
  4. 采用ffi库调用C++库,ref资料1
    ref资料2
    ref资料3
    其它的请自行百度,此处就不细细阐述了。
  5. 图片处理有两种,一种是opencv4nodejs(node版本大于10.x,我用的是10的最后一版本,最新版本的用的python3.3,编译问题太多),一种是jimp,都有方法实现,我推荐opencv,处理速度快,但是配置环境略复杂。
    资料看官方的npm即可,其余资料参考python调用opencv的方法类似。
  6. 此次主要针对window版本的dll,linux调用方法一样,将路径换位自己的路径即可,文件名为.so

二、ffi安装及环境安装

1、安装 Visual Studio 15 生成工具 2017
利用 微软自带的安装exe  【vs_BuildTools.exe】
目录:C:\Users\Administrator\.windows-build-tools,脚本安装时,会因为安装包过大和网络问题,导致安装失败。2、指定编译MSBuild.exe位置,因为2019和上述装的2017都有这个exe,最好使用2017的,2019我安装失败了。
npm config set msbuild_path "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe"3、指定python版本,还是建议2.7,其他高版本问题太多,我的3.8.5(不推荐)
npm config set python C:/Python27
npm config set python C:/python3.8.53、安装gyp
npm install node-gyp -g
或者
npm install --global node-gyp@latest4、安装ffi ref
npm install ffi -g
npm install ref -g
成功编译

三、opencv4nodejs的安装

手动安装opencv的环境,设置环境变量
OPENCV_BIN_DIR=E:\commonsoft\opencv\build\x64\vc14\bin
OPENCV_INCLUDE_DIR=E:\commonsoft\opencv\build\include
OPENCV_LIB_DIR=E:\commonsoft\opencv\build\x64\vc14\lib此处这么安装,成功率90%
set OPENCV4NODEJS_DISABLE_AUTOBUILD=1
npm i -g opencv4nodejs

四、代码结构

├─.electron-vue
├─.idea
├─build
│  └─icons
├─dist
│  ├─electron
│  └─web
├─images
├─src
│  ├─main
│  │  ├─inc
│  │  ├─lib
│  │  │  ├─X64
│  │  │  └─X86
│  │  └─modual
│  │      ├─img
│  │      │  ├─faces
│  │      │  └─test
│  │      └─log
│  └─renderer
│      ├─assets
│      ├─components
│      │  └─LandingPage
│      ├─router
│      └─store
│          └─modules
├─static
└─test├─e2e│  └─specs└─unitmodual文件夹为人脸识别工作目录
lib文件夹为放置dll文件路径的地方,x86 x64 为对应的版本
img 图片路径(faces 为 drawFace 的操作路径 test 是 cvImages 的操作路径)

五、代码调用实例及说明


const arc_face = require('./face_engine');
const path = require('path');
const config = require('./config');
const m = require('./logger');
const client = require('./clients');
const imageHelper = require('./face_cv_image');
const fsUtil = require('./fileUtils');// 设置dll路径
let dllPath = "";
if (process.env.NODE_ENV !== 'development') {dllPath = require('path').join(__dirname, '../../main/lib/X64').replace(/\\/g, '\\\\')
}else{dllPath = require('path').join(__dirname, '../lib/X64').replace(/\\/g, '\\\\')
}
// 添加DLL所在目录到环境变量
process.env['PATH'] = `${process.env.PATH};${dllPath}`;// 初始化接口
const arc = new arc_face(config.lib_win64);Object.prototype.toString = function(){return JSON.stringify(this);
};Date.prototype.toLocaleString = function() {return this.getFullYear() + "-" + (this.getMonth() + 1) + "-" + this.getDate() + " " + this.getHours() + ":" + this.getMinutes() + ":" + this.getSeconds();
};this.test_arc = async () => {try{let dataInfo = arc.getActiveFileInfo();if (null != dataInfo){let start = new Date(parseInt(dataInfo.startTime) * 1000);let end = new Date(parseInt(dataInfo.endTime) * 1000);m.logger.info("expire date is from %s to %s, please check the date for expired.thank you.",start.toLocaleString(),end.toLocaleString());if (new Date().getTime() > end){m.logger.warn('your arc soft is expired,please change the file to continue use it,thank you.');return;}}client.get('active', (err, res) => {// 激活if (!res || parseInt(res) !== 1){let ib = arc.activeFaceEngine(config.appId,config.appKey);client.set('active',ib?1:0);}else{m.logger.info("engine has already initialed, do not repeat active");}});let version = arc.getVersion();m.logger.info("current verson is %s",version.Version);// 初始化引擎arc.initialFaceEngine(16,50);// 设置可信度arc.setLiveParam(0.5,0.7);let img_path1 = path.join(__dirname, './img/1.jpg');let img_path2 = path.join(__dirname, './img/2.jpg');let img_path3 = path.join(__dirname, './img/3.jpg');// jimp 处理图片// let asvl1 = await imageHelper.parseImage(img_path1,false);// let asvl2 = await imageHelper.parseImage(img_path2,false);// let asvl3 = await imageHelper.parseImage(img_path3,false);// opencv 处理图片let asvl1 = await imageHelper.cvImages(img_path1,false,path.join(__dirname, './img/test'));let asvl2 = await imageHelper.cvImages(img_path2,false,path.join(__dirname, './img/test'));let asvl3 = await imageHelper.cvImages(img_path3,false,path.join(__dirname, './img/test'));// 检测人脸let data1 = arc.detectFacesEx(asvl1.imageData);let data2 = arc.detectFacesEx(asvl2.imageData);// 提取特征值let feature1 = arc.extractFeature(asvl1.imageData, data1.multi.faceRect[0], data1.multi.faceOrient[0]);let feature2 = arc.extractFeature(asvl2.imageData, data2.multi.faceRect[0], data2.multi.faceOrient[0]);if (!feature1 || !feature2){m.logger.error("feature1 or feature2 is null. please check.");return;}// console.log("feature1",feature1)// console.log("feature2",feature2)// 比较let sim = arc.compareFeature(feature1.nav,feature2.nav);if (sim < 0){m.logger.info("similar is %d,is not the same person.",sim);return;}if (sim > 0.8){m.logger.info("similar is %d,is the same person.",sim);}else{m.logger.info("similar is %d,is not the same person.",sim);}// base64 转 feature 测试 ,实际效果会差0.02let f1 = arc.base64ToFeature(feature1.nab.featureBuffer);let f2 = arc.base64ToFeature(feature2.nab.featureBuffer);let ff = arc.compareFeature(f1,f2);if (ff > 0.8){m.logger.info("similar is %d,is the same person.",ff);}else{m.logger.info("similar is %d,is not the same person.",ff);}// 释放人脸指针arc.release(f1.feature);arc.release(f2.feature);// 单体检测let ib = arc.processEx(asvl3.imageData,false);if (!ib){m.logger.error("single process checked failed.");return;}arc.getSexInfo();arc.getAgeInfo();arc.getAngleInfo();arc.getLivenessScore(false);// 测试画框let isIR = false;let asvl5 = await imageHelper.cvImages(img_path1,isIR);let infos = arc.detectFacesEx(asvl5.imageData);let filePath = path.join(__dirname, './img/faces');await fsUtil.dirExists(filePath);imageHelper.drawFace(img_path1,infos.multi,true,filePath);// detect 和 process 系列let fileCv = path.join(__dirname, './img/test');await fsUtil.dirExists(fileCv);let asvl6 = await imageHelper.cvImages(img_path1,isIR,fileCv);let faces = arc.detectFaces(asvl6,false);let info = arc.processNone(asvl6,false);arc.getLivenessScore(false);// console.log('info',info);// 释放 函数中已经释放调用的指针arc.unInitialEngine();client.quit();}catch (e) {m.logger.info("some error happened.%s",e.toString());arc.unInitialEngine();client.quit()}
};this.test_arc();

六、安装及使用

# install dependencies
npm install# serve with hot reload at localhost:9080
npm run dev# build electron application for production
npm run build# run unit & end-to-end tests
npm test# 测试人脸部分
node face_test.js

七、常见问题

1、Dynamic Linking Error: Win32 error 126
这个错误有三种原因(1)通常是传入的 DLL 路径错误,找不到 Dll 文件,推荐使用绝对路径。
(2)如果是在 x64 的node/electron下引用 32 位的 DLL,也会报这个错,反之亦然。要确保 DLL 要求的 CPU 架构和你的运行环境相同。
DLL 还有引用其他 DLL 文件,但是找不到引用的 DLL 文件,可能是 VC 依赖库或者多个 DLL 之间存在依赖关系。
设置dll的工作的环境变量
process.env['PATH'] = `${process.env.PATH};${'E:/arface_node/arface_nodejs/src/main/lib/X64'}` //添加DLL所在目录到环境变量
Dynamic Linking Error: Win32 error 127:DLL
(3)没有找到对应名称的函数,需要检查头文件定义的函数名是否与 DLL 调用时写的函数名是否相同。2、electron-vue 运行问题,如果提示app of undefined 类似的问题,在创建窗体时加入如下模块
enableRemoteModule:true, // 加入此句就可以获取app模块,就不会报错了3、在node里面,指针 -> 缓存(buffer),
如 let a = new (typedef.MInt32.size) 表示 a*,
a.deref() 可以取出指针中的值,
普通变量 b, 那 b.ref() 表示 b*
.size 相当于C++ 里面的 size_t4、调用C++ 第一步就是对应 数据类型// ref提供了C++的基本数据类型和定义,nodejs参数类型和C语言参数类型转换
const ref = require('ref');
typedef.MLong = ref.types.long;
typedef.UMLong = ref.types.uint32;
typedef.MFloat = ref.types.float;// 提供 C++ 结构体定义方法
const StructType = require('ref-struct');
typedef.__tag_rect = StructType({left: typedef.MInt32,top: typedef.MInt32,right: typedef.MInt32,bottom: typedef.MInt32
});
// 提供 C++ 数组定义方法
const ArrayType = require('ref-array');
ppu8Plane: ArrayType(ref.refType(typedef.MUInt8), 4),
ref.refType(XXX)表示指针5、C++接口映射
// 一种是不带回调函数的,如下:
ffi.Library(libFile, {// 映射的接口名称 C++接口,对应的数据类型ASFGetActiveFileInfo: [TypeDef.MRESULT,[TypeDef.LPASF_ActiveFileInfo // [out] 激活文件信息]]
}// 一种是带回调函数的调用
let libname = ffi.Library('./libname', {'setCallback': ['void', ['pointer']]
});let callback = ffi.Callback('void', ['int', 'string'],function(id, name) {console.log("id: ", id);console.log("name: ", name);
});libname.setCallback(callback);
// 退出时引用回调指针以避免GC(垃圾回收)
process.on('exit', function() {callback
});6、指针拷贝操作,用到 linux 中的 libc 操作
分配指定大小的空间指针: libc.malloc(size);
初始化指针:libc.memset(*p,offset,size);
指针拷贝:libc.memcpy(*to, *from ,size);7、结合node中的buffer,将指针拷贝至buffer
const arr = new Buffer(TypeDef.MByte.size);
for (let i = 0; i < _feature.featureSize; i++) {libc.memcpy(arr.address(), feature.feature.address() + i * TypeDef.MByte.size, TypeDef.MByte.size);this.pointers.push(feature.feature);_normal.feature.push(ref.get(arr, 0, TypeDef.MByte));
}
arr.deref()即取出指针中的值8、分配的指针空间一定要释放
libc.free(*p)

了解更多人脸识别产品相关内容请到虹软视觉开放平台哦

虹软人脸识别ArcSoft3.0NodeJs 版本实现相关推荐

  1. 初次使用虹软人脸识别SDK C++版本

    本文章是基于虹软人脸识别SDK3.0,VS2019 首先,下载虹软人脸识别SDK,按照此目录下的PDF文件完成工程配置. 配置完成后,需要在以下目录将从官网获取的APPID以及SDKKEY进行填写,然 ...

  2. java用虹软人脸识别SDK实现人脸识别,运行ArcSoft的Java版本Demo出错,未检出人脸

    java.lang.UnsatisfiedLinkError: Can't load library: d:\face_libs\libarcsoft_ java用虹软人脸识别SDK实现人脸识别 网上 ...

  3. java用虹软人脸识别SDK实现人脸识别,运行ArcSoft的Java版本Demo出错,未检出人脸(已解决)

    java用虹软人脸识别SDK实现人脸识别,运行ArcSoft的Java版本Demo出错,未检出人脸问题已解决!!! 原因: 虹软人脸识别SDK版本问题! 下载的java版本的demo的SDK是arcs ...

  4. 虹软人脸识别WPF版本,含活体检测

    虹软人脸识别WPF版本,3.0类库,含活体检测 源码地址: https://gitee.com/dacaba/arcface-demo-csharp-wpf3 将对应appid和appkey替换App ...

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

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

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

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

  7. 基于RTSP视频流的Java后台服务端虹软人脸识别

    1 概述       人脸识别技术是随着技术发展而产生的生物识别技术,目前已广泛应用于安防领域,主要用于身份验证和身份识别.视频监控是安防系统常见的一种表现形式,需要部署各种摄像头,包括网络摄像头IP ...

  8. 虹软人脸识别 - 人脸特征数据的存取

    虹软人脸识别 - 人脸特征数据的存取 文章目录 虹软人脸识别 - 人脸特征数据的存取 一.简介 二.数据库应用 1. 连接数据库 2. 建表 3. 注册人脸并保存其特征值到数据库 4. 获取人脸特征数 ...

  9. Android 虹软人脸识别获取数据的方法

    前言 最近app要上一个新的功能 在客户点击购买的时候 记录客户的基本信息 比如年龄和性别 为后期做大数据分析做铺垫 在网上找第三方 找到了虹软人脸识别 在这里吐槽一下 免费的虹软 真是很坑 客服没人 ...

最新文章

  1. 中科院遗传发育所王秀杰团队鉴定出10种潜在的2019-nCoV蛋白酶抑制剂
  2. android Java BASE64编码和解码一:基础
  3. 特征因子是什么意思_生态因子作用的一般特征
  4. 创建型模式 简单工厂模式
  5. nginx+memcached+captcha_server实现验证码服务器
  6. 随想录(用python开发网站)
  7. 修改成绩用c语言怎么编程,用C语言编程平均分数
  8. 摘抄和总结--确保搞砸人工智能项目的十种方法
  9. Springboot实现filter拦截token验证和跨域
  10. win10 更新 英特尔显示器音频 后显示器音箱没有声音
  11. 最全整理浏览器兼容性问题与解决方案
  12. 量子计算机原理 不确定,【图片】不确定性原理对量子纠缠的解释【经典物理吧】_百度贴吧...
  13. 程序员这高薪岗位只有计算机专业的能做?
  14. prometheus入门实例
  15. https://www.cloudmidi.net/ableton-live-11-suite-v11-0-macos.html
  16. Java8 Stream API 详细使用指南
  17. VMware -- 克隆虚拟机
  18. Python 计算思维训练——输入和错误处理练习(二)第三关
  19. CP-VTON学习笔记
  20. 考研党看这里,福昕阅读器领鲜版让你如虎添翼

热门文章

  1. 大学学了一年Python之后开始兼职,平均每个月赚3030块
  2. 怎么在多个快递单号中快速找出没有物流的单号
  3. jupyter 快捷键
  4. 关于Rstudio最新版本中Biobase和GEOquery安装的问题
  5. tomcat基本介绍
  6. js判断时间是否为当天(今天是今天)
  7. python延时执行函数_一日一技:在 Python 中实现延迟调用
  8. mmcv/_ext.cpython-36m-x86_64-linux-gnu.so: undefined symbol: _ZN6caffe28Type
  9. WIN7 bootmgr is conmpressed 无法开机
  10. http升级为https全过程(通过nginx安装SSL证书)