文章目录
虹软人脸识别 - 基于QT的桌面客户端与微信小程序服务器设计
简介
虹软公司为了帮助巨量的企业打破技术壁垒,快速运用机器视觉技术,让AI真正为行业赋能,为社会造福,将其二十多年来经行业检验积累并已广泛应用于各种智能设备上的人工智能引擎开放供开发者免费使用,并且提供了多种平台的多种语言接口。尤其是C/C++接口,使得人脸识别等功能可以轻易集成于基于C++开发的桌面客户端或服务器中。
本文将基于虹软公司的人脸识别SDK 3.0Windows(X64),C/C++接口与QT等库简单介绍桌面客户端,微信小程序,以及无线嵌入式摄像头软件,服务器开发中的核心技术。本项目为一款智能酒店的解决方案,实现住客、访客、工作人员的人脸注册及识别功能。
桌面客户端
桌面客户端主要实现两个功能,实现人脸的注册与识别。需要注意的是,虹软人脸识别(ArcFace)引擎分为视频处理以及照片处理两种模式,对于注册,考虑为了有效提取人脸特征,使用照片处理方式;而对于识别过程,使用视频处理方式,在ArcFace3.0版本中还提供对视频的人脸追踪,避免重复识别,从而提高了效率。因此,本设计同时初始化两种引擎,处理不同需求下的人脸检测功能。
两种模式通过ASFInitEngine的detectMode参数指定,可选项如下:
//检测模式
enum ASF_DetectMode{
ASF_DETECT_MODE_VIDEO = 0x00000000, //Video模式,一般用于多帧连续检测
ASF_DETECT_MODE_IMAGE = 0xFFFFFFFF //Image模式,一般用于静态图的单次检测
};
具体检测与特征提取方法可以参考虹软的Github仓库。
计算机视觉领域常用OpenCV对图像进行处理,图像以cv::Mat存储,而为了将最终结果显示到QT的Widgets中,应使用QImage,这里提供一种转换方式:
static QImage cvMat2QImage(const cv::Mat& mat)
{
return QImage(mat.data, mat.cols, mat.rows, QImage::Format_RGB888);
}
实际使用中有时会发现,对于一个已经注册的人脸,当其刚进入屏幕中时,由于摄像头曝光时间等原因,获取到的某些帧可能存在人脸匹配置信度(confidence level,虹软推荐在0.8左右)无法达到要求的情况;同时还存在某些角度的人脸突然识别为未知等异常情况。由于本设计需要记录人员过往信息,因此设计如下时域滤波算法。
if (++index == 5)index = 0; //这里设置了滤波器的阶数;
switch (curr_person.type)
{
case EMPTY:filter[index] = 0; break; //无人将滤波器填充0;
case UNKNOWN:filter[index] = -1; break; //有未知人员填充-1;
default:filter[index] = 1; //有已知人员填充+1,
recordPerson.type = curr_person.type; //并且保存当前已知人员;
recordPerson.name = curr_person.name;
break;
}
int sum = std::accumulate(filter.begin(), filter.end(), 0);
if (sum >= 3) //设置一个置信度,比如这里为3,超过此值,确信有已知人员;
{
if (preState == EMPTY)
{
passModel->addAppearance({
recordPerson.type,recordPerson.name
,QDateTime::currentDateTime(),{
} });//记录出现时间
preName = recordPerson.name;
}
preState = recordPerson.type;
}
else if (sum <= -3) //设置一个置信度,比如这里为-3,低于此值,确信有未知人员;
{
if (preState == EMPTY)
{
passModel->addAppearance({
UNKNOWN,u8"未知人员"
,QDateTime::currentDateTime(),{
} });//记录出现时间
preName = recordPerson.name;
}
preState = UNKNOWN;
}
else //其他情况,认为无人存在
{
if (preState != EMPTY)//这里检测到上一次调用并非无人,说明一定是从某人转换为无人,因此preName是有效的;
{
passModel->addDisappearance({
{
},preName,{
}
,QDateTime::currentDateTime() });//记录离开时间
}
preState = EMPTY;
}
通过配合各Widgets,可以在界面上实现多样的功能,结合人脸识别引擎,即可完成桌面客户端的全部业务逻辑。模拟实际业务场景,效果如下图:
微信小程序
登记
微信小程序端可以实现用户的登记,并且在解决方案中,当有人经过猫眼时,小程序可以接收到来自服务器的实时推送。
前端使用chooseImage以及uploadFile发送用户选择的照片,在请求头中写入用户昵称与openid,以区分不同用户。服务器响应该请求,调用虹软人脸识别模块,对面部信息框选,保存到服务器本地。前端可通过URL访问该图片,从而更新界面显示。本设计前端使用了微信小程序官方UI库WeUI。
handleChoose: function () {
var that = this;
wx.chooseImage({
count: 1, //最多可以选择的图片总数
sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var tempFilePaths = res.tempFilePaths;
var timestamp = that.getTimeStamp();
wx.showLoading({
title: '上传中',
})
wx.uploadFile({
url: app.data.domain + "multipart",
filePath: tempFilePaths[0],
name: 'uploadFace',
formData: {
'username': app.data.userNickName,
'openid':app.data.openid
},
header: {
"Content-Type": "multipart/form-data"
},
success: (res) => {
var param = JSON.parse(res.data)
var gender = "";
if (param['state'] ==