wrs-arcface虹软人脸识别
前言
虹软人脸识别组件,支持活体识别、离线识别、图片人脸特征识别、图片是否同一人对比、相机人脸识别或对比,虹软免费版请使https://ext.dcloud.net.cn/plugin?id=6084
功能
- 支持活体识别、离线识别
- 图片人脸特征识别(年龄、性别、3DAngle)
- 两张图片是否是同一人对比
- 相机活体识别出人脸,用于人脸注册保存到本地,便于后面身份鉴定时作对比
- 相机活体人脸对比,用于鉴定身份,常用于支付前活体人脸身份鉴定
激活引擎
使用之前需要激活引擎,虹软官方注册账号,获取APP_ID、SDK_KEY,注意创建应用的时候iOS需要绑定包名(这里iOS的包名对应自定义基座时的Bundle ID(AppID)),Android需要绑定包名和签名(这里的包名对应自定义基座时Android包名,这里签名是打包证书对应的sha1值)
激活引擎可以放到App.vue的onLaunch里去,每次启动的时候激活就行了
var arcface = uni.requireNativePlugin("wrs-arcface");
var options = {};
options.appid = "xxxxx";
switch (uni.getSystemInfoSync().platform) {case 'android':options.sdkkey = 'xxx';break;case 'ios':options.sdkkey = 'xxx';break;default:break;
}
arcface.activeEngine(options, (resp) => {if (resp.result) {console.log("激活成功");} else {console.log("激活失败");}this.showMsg("引擎激活结果:" + JSON.stringify(resp))
});
获取图片人脸信息(年龄、性别、3DAngle)
var options = {url: “” // 本地图片地址或网络图片};
arcface.getImageFaceFeature(options, (resp) => {if (resp.result) {console.log("识别成功");} else {console.log("识别失败");}this.showMsg("图片识别结果:" + JSON.stringify(resp))
});
设置相机检测角度
arcface.setVideoAngle({videoAngle: "all" // 0:仅检测0度 90:仅检测90度 180:仅检测180度 270:仅检测270度 all:检测0、90、270、180全角度
});
判断2个人脸图是否是同一个人
var options = {url1: “”, // 图片1地址,本地图片地址或网络图片url2: ”“ // 图片2地址
};
arcface.getSimilarity(options, (resp) => {if (resp.result) {var similarity = resp.similarity;if (similarity >= 0.80) { // 一般相似度大于0.8基本上就是同一个人了console.log("是同一个人");} else {console.log("不是同一个人");}}this.showMsg("获取相似度结果:" + JSON.stringify(resp))
});
摄像机人脸识别或人脸身份对比鉴定
<wrs-arcfacevideo ref='arcfacevideo' :style="'width:'+width+'px;height:'+height+'px;'" :config="config" @resultCallback="resultCallback"></wrs-arcfacevideo>config: {mode: 'recognize' ,// 模式,支持recognize、compare,recognize表示从摄像头识别人脸,一般用于人脸注册保存到本地,compare表示从摄像头识别出某个人,一般用于身份鉴权bgColor: "#000000", // 背景颜色anchorFrame: {bgImage: frameImage, // 人脸框图片left: left, // 人脸框左边距,单位 dptop: top, // 人脸框上边距width: frameWidth,// 人脸框宽度height: frameHeight // 人脸框高度},startFace:{}}
config属性:
- bgColor: 背景颜色
- anchorFrame: 人脸框
- anchorFrame.bgImage: 人脸框图片
- anchorFrame.left: 人脸框左边距,单位 dp
- anchorFrame.top:人脸框上边距
- anchorFrame.width: 人脸框宽度
- anchorFrame.height: 人脸框高度
- startFace: 开始识别人脸,如果config里有startFace参数则自动开始人脸业务,否则需要手动调用startFace()方法
config.startFace对象的参数如下: - mode: 模式,支持recognize、compare,recognize表示从摄像头识别人脸,一般用于人脸注册保存到本地,compare表示从摄像头识别出某个人,一般用于身份鉴权
- compareImage 人脸对图片,用于mode为recognize识别对比模式时作相机对比图片
- compareImage.type: 图片类型,支持url、base64,url表示图片地址,支持本地地址和网络地址,base64表示图片base64的字符串
- compareImage.value:图片类型对应的值
- similarity: 相似度,用于mode为recognize模式时相似度大于这个值时认为是同一个人
- liveness: 是否需要活体识别
- faceNeedInRect: 人脸是否需要在anchorFrame人脸框内
- needBase64Image: 识别到的图片是否需要进行base64编码返回,base64编码在Android上比较慢
- saveImageFilePath: 识别到的图片是否需要保存为文件,如果不需要saveImageFilePath值不用传或传空
方法:
停止摄像头
this.$refs.arcfacevideo.stop();
开始摄像头,组件默认已经开启摄像头
this.$refs.arcfacevideo.start();
事件
@resultCallback
mode模式为recognize时,识别到人时回调
mode模式为compare时,识别到人,且大于等于相似度时回调
开始识别人脸
var params = {};
this.$refs.arcfacevideo.startFace(params);
params参数见上面的config.startFace
切换相机前后摄像头
this.$refs.arcfacevideo.switchCamera()
完整demo
index.nvue
<template><div><text>虹软(免费版)人脸识别</text><button @click="activeEngine()">激活引擎</button><button @click="getImageFaceFeature()">获取图片人脸信息(年龄、性别、3DAngle)</button><button @click="getSimilarity()">判断2个人脸图是否是同一个人</button><button @click="video_page()">摄像头识别</button><text class="log">{{msg}}</text></div>
</template><script>String.prototype.endWith = function(endStr) {var d = this.length - endStr.length;return (d >= 0 && this.lastIndexOf(endStr) == d)}var arcface = uni.requireNativePlugin("wrs-arcface");export default {data() {return {msg: "",}},methods: {activeEngine: function() {var options = {};options.appid = "xxx";switch (uni.getSystemInfoSync().platform) {case 'android':options.sdkkey = 'xxx';break;case 'ios':options.sdkkey = 'xxx';break;default:break;}arcface.activeEngine(options, (resp) => {if (resp.result) {console.log("激活成功");} else {console.log("激活失败");}this.showMsg("引擎激活结果:" + JSON.stringify(resp))});},getImageFaceFeature: function() {var path = "_www";var absPath = plus.io.convertLocalFileSystemURL(path);console.log("absPath:" + absPath);// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾if (absPath.endWith('/')) {absPath = absPath.substring(0, absPath.length - 1);}var imagePath = absPath + "/static/1.jpeg";console.log("imagePath:" + imagePath);var options = {url: imagePath};arcface.getImageFaceFeature(options, (resp) => {if (resp.result) {console.log("识别成功");} else {console.log("识别失败");}this.showMsg("图片识别结果:" + JSON.stringify(resp))});},getSimilarity: function() {var path = "_www";var absPath = plus.io.convertLocalFileSystemURL(path);// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾if (absPath.endWith('/')) {absPath = absPath.substring(0, absPath.length - 1);}var url1 = absPath + "/static/yifei1.jpeg";var url2 = absPath + "/static/yifei2.jpeg"var options = {url1: url1,url2: url2};arcface.getSimilarity(options, (resp) => {if (resp.result) {var similarity = resp.similarity;if (similarity >= 0.80) { // 一般相似度大于0.8基本上就是同一个人了console.log("是同一个人");} else {console.log("不是同一个人");}}this.showMsg("获取相似度结果:" + JSON.stringify(resp))});},video_page: function() {uni.navigateTo({url: './video_face'});},showMsg: function(msg) {console.log(msg);this.msg = msg;}}}
</script><style>.btn {margin-top: 25rpt;}
</style>
video_face.nvue
<template><div><wrs-arcfacevideo ref='arcfacevideo' :style="'width:'+width+'px;height:'+height+'px;'" :config="config"@resultCallback="resultCallback"></wrs-arcfacevideo></div>
</template><script>String.prototype.endWith = function(endStr) {var d = this.length - endStr.length;return (d >= 0 && this.lastIndexOf(endStr) == d)}export default {data() {const {windowWidth,windowHeight,statusBarHeight} = uni.getSystemInfoSync();var path = "_www";var absPath = plus.io.convertLocalFileSystemURL(path);// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾if (absPath.endWith('/')) {absPath = absPath.substring(0, absPath.length - 1);}var imagePath = absPath + "/static/person.png"var frameImage = absPath + "/static/facesign_border.png";// 人脸框宽度var frameWidth = windowWidth * 0.8;// 图片比例var imageRatio = 298 / 343;// 人脸框高度var frameHeight = frameWidth / imageRatio;var left = (windowWidth - frameWidth) / 2.0;var top = 100;var bottom = windowHeight - frameHeight - top;return {height: windowHeight,width: windowWidth,config: {bgColor: "#000000", // 背景颜色anchorFrame: { // 人脸框bgImage: frameImage, // 人脸框图片left: left, // 人脸框左边距,单位 dptop: top, // 人脸框上边距width: frameWidth, // 人脸框宽度height: frameHeight // 人脸框高度},startFace:{} // 如果config里有startFace参数则自动开始人脸业务,否则需要手动调用startFace()方法},msg: ""}},onReady(){this.startFace(); // 注意调用startFace()方法的时机,相机},onLoad:function() {console.log("onLoad");console.log("onLoad this:" + this);var _self = this;setTimeout(function(){console.log("setTimeout");console.log("setTimeout this:" + this);},1000);},onShow() {console.log("onShow");console.log("onShow this:" + this);},onUnload() {this.$refs.arcfacevideo.stop();},methods: {startFace: function(){console.log("startFace000");var mode = "recognize";var base64 = "";try {base64 = uni.getStorageSync('faceData_key');if (base64 && base64.length > 0) {mode = "compare";} else {mode = "recognize";}} catch (e) {// errorconsole.log("getStorageSync error:" + e.message);}var saveImageFilePath = "";switch (uni.getSystemInfoSync().platform) {case 'android':saveImageFilePath = "/sdcard/Download/face.png";break;case 'ios':var absPath = plus.io.convertLocalFileSystemURL('_documents');// Android获取的absPath以/结尾,iOS获取的absPath不是/结尾if (absPath.endWith('/')) {absPath = absPath.substring(0, absPath.length - 1);};saveImageFilePath = absPath + "/face.png";break;default:break;} var params = {mode: mode, // 模式,支持recognize、compare,recognize表示从摄像头识别人脸,一般用于人脸注册保存到本地,compare表示从摄像头识别出某个人,一般用于身份鉴权compareImage: {type: 'url', // 类型,支持url、base64,url表示图片地址,支持本地地址和网络地址,base64表示图片base64的字符串value: saveImageFilePath}, // 比较图片地址similarity: 0.8, // 相似度liveness: true, // 是否活体识别faceNeedInRect: false, // 人脸是否需要在anchorFrame人脸框内needBase64Image: false, // 识别到的图片是否需要进行base64编码返回,base64编码在Android上比较慢saveImageFilePath: saveImageFilePath // 识别到的图片是否需要保存为文件,如果不需要saveImageFilePath值不用传或传空};this.$refs.arcfacevideo.startFace(params);},resultCallback: function(resp) {var str = JSON.stringify(resp);console.log("resultCallback:" + str);if (null != resp.detail) {if(this.model == "compare") {console.log("识别成功");} else {var imageBase64 = resp.detail.imageBase64;try {uni.setStorageSync('faceData_key', imageBase64);} catch (e) {console.log("setStorageSync 保存失败:" + e.message);}}this.$refs.arcfacevideo.stop();uni.navigateBack({delta: 1});} else {console.log("识别失败");}}}}
</script><style></style>
联系方式:QQ(252797991)
如果觉得可以就点个👍吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!
相关文章:

C++指针与引用的区别
(1)指针是一个变量,本身占有内存,内存中存储的是所指向对象的地址。引用是内存的别名。 (2)指针可以通过解引用的方式,取出所指向内存中的值。引用没有解引用。 (3)指针可…

Linux08-日志
目录 一、systemd的日志 1.1、sytemd-journald与systemd日志 1.2、systemd日志的持久化 二、系统常规日志 2.1、系统日志概述 2.2、查看系统日志文件 2.3、日志的轮转 2.4、分析系统日志 2.5、使用logger发送消息到日志 RHEL7的日志由2个服务负责记录,分别…

Java的小实验——各种测试以及说明
日期:2018.10.07 星期五 博客期:014 一、Java中的位运算 代码如下: 1 package Morts107;2 3 public class Test107 {4 public static void main(String[] args) {5 int z;6 z 13>>1;//00001101(13)---------------…

C++内存的分区
C内存分为四个区: (1)代码区:存放代码转译成的二进制代码。 (2)全局区:存放全局变量、静态变量(static)、常量(如字符串常量)。 全局区中还包含一…

SpringCloud的服务网关zuul
演示如何使用api网关屏蔽各服务来源 一、概念和定义 1、zuul最终还是使用Ribbon的,顺便测试一下Hystrix断路保护2、zuul也是一个EurekaClient,访问服务注册中心,获取元数据,使用本地的Ribbon负载均衡,Hystrix断路保护&…

wrs-tuya-cloud
前言 wrs-tuya-cloud是涂鸦官网针对云开发的插件,包含垂直品类硬件API(万能红外开放能力、设备连接服务、设备OTA固件升级、实时音视频、睡眠带开放能力、体脂秤开放能力、智能门锁开放能力、视频云存储 、邮件服务 、 语音消息服务、消息推送服务、短信服务 、内测…

Windows Server 2016 笔记
从业界普遍实践结果来看,Windows Server在服务器领域真是不太好用。但是,有些时候由于种种原因不得不用,所以还是有必要了解一下的。今天参加了一个Windows Server的培训,主要面对Windows Server 2016,写下这篇博客备忘…

(办公)网页发送到桌面快捷方式怎么做
转载自百度:https://jingyan.baidu.com/article/f79b7cb303d50a9145023e6e.html 有时候一个网页我们需要经常用到,每次找那个需要的网页很耗时间,那么我们怎么把我们需要的网页发送到桌面快捷方式呢? 这样下次我们直接点击桌面上的快捷方式就…

C++程序编译过程
程序编译的过程,是将源代码转换为计算机可执行的机械语言的过程。分为预处理、编译、汇编、链接四步。 (1)预处理:对程序进行预处理,比如将头文件的代码直接赋值到当前代码中等等. (2)编译&am…

Java的注释(详细版)
注释是对代码进行必要的说明,以便于后期的修改、维护和升级。Java的注释分为三种:第一种是**单行注释**:用双斜杠“//”来进行实例://单行注释第二种是**文档注释**:用斜杠“/”和星号“*”来进行实例:/***…

Hadoop的存储架构介绍
http://lxw1234.com/archives/2016/04/638.htm 该文章介绍了Hadoop的架构原理,简单易懂。 目前公司提供Hadoop的运算集群BMR,可以直接申请集群资源。转载于:https://www.cnblogs.com/blog-of-Fourier/p/6809811.html

编译OpenSSH8.4的RPM包及升级
目录 一、安装相关依赖包 二、创建rpmbuild目录并下载源码 三、打包及排错 四、升级到OpenSSH 8.4p1 以下是打包好的OpenSSH 8.4p1,包括7个rpm包,欢迎下载使用。 OpenSSH-8.4p1-Bundle 一、安装相关依赖包 根据以往经验,需要安装wget、…

centos 系统使用verdaccio搭建npm私库
.安装nodejs yum install -y nodejs 2.安装verdaccio npm install -g verdaccio --unsafe-perm 3.配置 a.修改配置文件 config.yaml,在其最后添加监听端口(使其可在外网访问) listen: 0.0.0.0:4873 b.对外开放4873端口 firewall-cmd --state …

视觉SLAM中PNP求解
PNP(Perspective-n-points)是SLAM中估计位姿的重要方法。已知条件为路标点在相机1中的相机坐标以及投影到相机2中的像素坐标,据此去估计相机1、相机2间的位姿。主要解法包括DLT、P3P、EPNP P3P 已知A、B、C在相机1坐标系下的坐标࿰…

Java程序的运行原理 用记事本编写Java代码
首先将Java代码写入源文件(.java)中→ 通过 javac 生成class文件(.class) → 再通过java命令执行程序:◆将class文件加载内存(相当于将东西输入大脑)◆检验class文件(大脑检查是否有语法等错误,若无误)◆将…

Linux下修改mysql的root密码后数据库消失怎么处理
Linux系统下如果没有通过password()函数修改mysql的root密码就会导致mysql数据库消失。有些人可能不知道而直接修改了mysql的root密码,于是产生了mysql数据库消失的问题,这个时候该怎么处理呢? 可以用下面的办法解决&a…

编译httpd-2.4.46的RPM包
目录 一、下载源码 二、编译&排错 2.1、第一次编译,解决依赖包问题。 2.2、第二次编译,解决anaconda导致的环境变量问题 2.3、第三次编译,解决apr版本过低问题 提供 apr-1.7.0、httpd-2.4.46 的RPM包下载。 apr-1.7.0-bundle.zip …

C/s模式B/S模式
C/s模式:是客户端/服务器(Client/Server)模式,主要指的是传统的桌面级的应用程序。比如我们经常用的信息管理系统。 C/S 客户端/服务器 例如QQ,网络游戏,需要下载客户端才能访问服务器的程序 B/S 浏览器/服务器 例如Intel…

分割catalina.out 每天生成一个文件
1. touch xxx(文件名字).sh 2. vim xxx.sh 写入 ----------------------- #!/bin/shcd dirname $0pwdddate %Y%m%dd7date -d7 day ago %Y%m%dcd ../logs/cp catalina.out catalina.out.${d}cat /dev/null > catalina.outrm -rf catalina.out.${d7} ----------…

、|| 和 、| 的区别(详尽版)
&&和|| 是逻辑运算符(也包括 !) 逻辑运算符含义&&逻辑与(两者为真才为真,一者为假即为假)︱︱逻辑或(两者为假才为假,一者为真即为真)!逻辑非(本来值的…

C++负数、小数如何保存
负整数 正整数直接按照源码存储,负整数按照补码存储。 原码、反码、补码 首先要清楚原码、反码、补码: 计算机中一个字节为8位,在此以一个字节为例: 原码: 十进制1:0000 0001 十进制-1:1000 …

MySQL00-这都不知道还TM学啥MySQL
目录 一、MySQL架构概述 1.1、客户端连接器 1.2、连接层 1.3、可插拔存储引擎 1.4、文件系统与文件 二、配置文件 三、数据文件 四、日志文件(以MySQL5.7.32为例) 4.1、错误日志 Error Log 4.2、一般查询日志 General Query Log 4.3、二进制日…

ORB_SLAM2 PnPSolver
EPNP:已知4组(默认)3D-2D匹配点,构建参考点,通过计算参考点的相机坐标,线性组合成路标点的相机坐标。然后使用ICP估计相机间的位姿变换。 需要注意的事,EPNP可以同时使用N组路标点构建M矩阵…

iOS开发UI篇—多控制器和导航控制器简单介绍
iOS开发UI篇—多控制器和导航控制器简单介绍 一、多控制器 一个iOS的app很少只由一个控制器组成,除非这个app极其简单。当app中有多个控制器的时候,我们就需要对这些控制器进行管理 有多个view时,可以用一个大的view去管理1个或者多个小view,控制器也是如…

值传递 和 地址传递 的区别(好多句话才可以说清)
要知道什么是**值传递**和**地址传递**,首先要知道什么是**基本数据类型**和**引用类型**。 Java的基本数据类型就八种(除了这八种之外都是引用类型):◆整型:byte(8位) short(16位) int(32位) long(64位)࿱…

日期类的时间从为什么是从1970年1月1日(格林威治时间)
I suspect that Java was born and raised on a UNIX system.UNIX considers the epoch (when did time begin) to be midnight, January 1, 1970.是说java起源于UNIX系统,而UNIX认为1970年1月1日0点是时间纪元. 但这依然没很好的解释"为什么",出于好奇&a…

MySQL从5.7.32升级到8.0.22
目录 一、备份与导出数据 二、升级到MySQL-8.0.22同时解决字符集问题 2.1、卸载MySQL-5.7.32 2.2、安装MySQL-8.0.22 2.3、修改配置文件 my.cnf 三、导入数据及配置 3.1、重新创建数据库wordpress 3.2、导入表结构和数据 3.3、启动httpd 今天,贫僧的个人博客…

50个顶级开源营销应用程序
显然,开源营销应用程序占有一席之地。如今,营销部门负责相当大比例的企业应用程序购买和部署决策。事实上,Gartner预测,到2017年,首席营销官(CMO)将比首席信息官(CIO)在I…

C++乘法的int越界问题
在做Leetcode 69. x 的平方根,出现了两种int越界的情况: 整数相乘越界 if(mid * mid < x)这样写的话,mid * mid可能越界,因此可以改为 if(mid < x/mid)整数本身越界 int n_r x;Leetcode给了个例子,x 21474…

C# DataSet与DataTable的区别和用法
DataSet是数据集,DataTable是数据表,DataSet存储多个DataTable。DataSet和DataTable像是专门存储数据的一个容器,在你查询数据库得到一些结果时可以存在里面。 DataSet功能强大有浏览、排序、搜索、过滤、处理分级数据、缓存更改等功能&#…