多种条件限制之下,如何完成真人实景游戏场景下的人脸识别开锁功能?云加社区邀请到腾讯科技产品经理—高树磊,分享他是如何用200行代码,从系统架构、硬件选型、到系统搭建,一步步地实现此精致小巧的人脸识别开锁应用的,但愿能和你们一道交流。
帮朋友实现了一我的脸识别进行开锁的功能,用在他的真人实景游戏业务中。几个月来运行稳定,体验良好,借着这次宅家的时间,整理一下这个应用的实现过程。 html
总的来讲需求描述简单,但因为约束比较多,在架构与选型上仍是花了些心思。python
因为该游戏还在线上服务中,此处就不放出具体操做的视频了。部署效果以下图所示:git
需求提出时比较明确,核心逻辑不复杂。github
毕竟是生意,因此在商言商,对实用性和成本要求很高,关键是不要影响游戏过程,同时保证玩家体验。算法
可能的架构方案有多种(不一样方案间的比较,在文末进行),下面展开说明一下最终上线的方案。json
流程与效果,请参考前文“玩家体验” 部份内容。网络
a. 腾讯云密钥对架构
修改配置文件,用于适配腾讯云帐号切换功能(测试帐号/正式帐号)。框架
b. 人员库IDdom
修改配置文件,用于指定不一样人员库(测试库/正式库)。
c. 水印提示
更换对应图片,实现更换水印。使用图片管理,而不是文字配置的缘由,是因为图片配置模式无需字库支持,无需配置显示大小,易于图案嵌入。因为所见即所得,对维护人员要求低。
d. 关机选项
可配置任务完成后,是否自动关机。用于游戏环境复位准备,减小复位工做量。
a. 系统运营管理
场景启动时,统一上电。认证经过后,自动关机,完成复位。
b. 故障处理
软硬件故障:没法开机、可开机无显示、可开机显示系统异常,可开机未知异常等等,更换树莓派或其它硬件。
网络故障:正常运行,没法认证,可查网络+查云日志,解决网络问题;
云产品异常:运行4个月,未发生过,能够忽略,如发生则联系云售后;
硬件成本:500~600元。
备件成本:按1:1备件,500~600元。
运行成本:云端0元,使用免费额度;电费网费,忽略不计。
树莓派:终端主控
摄像头:视频输入
传感器:超声波测距
显示屏:视频输出
继电器:控制电磁锁
电磁锁:控制保险箱门
图片识别:使用图片识别,而非视频流,减小对网络带宽要求。
识别要求低:欠曝光照片也有高识别率。
触发识别:玩家在场景内活动时间长,触发模式避免了高频认证、误开锁状况,同时下降认证成本。
测距选型:超声波传感器技术成熟,成本低(3元);激光传感器成本高(30元)
多进程:视频处理与监测鉴权由两个进程实现,避免了阻塞等状况,同时使用进程间通讯,实现可靠交互。
a. 注册帐号
按文档指引,获取API密钥
b. 配置人脸识别
访问官网控制台,经过“新建人员库->建立人员->上传照片”,创建认证基础。
其中所使用的“人员库ID”是关键信息,用于后续API调用识别时,指定认证动做匹配的人员库。
注:因为此案例只识别一我的员,无需对人员ID进行匹配,故不用指定人员ID。
a. 安装系统
访问 www.raspberrypi.org 获取镜像,并进行安装。注意必须安装桌面版,不然须要单独管理HDMI输出。
b. 配置网络
进入命令行,执行 "raspi-config",选择"Network Options",配置WiFi接入点。为了固定IP,编辑 /etc/dhcpcd.conf 文件,添加配置信息。
`
# 具体内容请参考你的本地网络规划 interface wlan0 static ip\_address\=192.168.0.xx/24 static routers\=192.168.0.1 static domain\_name\_servers\=192.168.0.1 192.168.0.2`
c. 安装腾讯云SDK
参考指引文档,安装调用腾讯云API的依赖库。
sudo apt\-get install python\-pip \-y pip install tencentcloud\-sdk\-python
d. 安装图像处理库
系统默认安装python2.7,但没有 opencv 库,须要安装。(下载包体积较大,默认源为国外站,比较慢。树莓派改国内源方法,请自行百度,并挑选离本身近的源站)
sudo apt\-get install libopencv\-dev \-y sudo apt\-get install python\-opencv \-y
e. 部署代码
访问github获取源码,将src文件夹内容,复制到 /home/pi/faceid 下。
更改 /home/pi/faceid/config.json 中的配置信息,必须改成你的 云API密钥(sid/skey)、人员库ID(facegroupid),其它配置按需调整。
f. 配置自启动
须要配置图形界面自启动,保证视频输出由HDMI接口输出至显示屏,编辑 /home/pi/.config/autostart/faceid.desktop 写入以下内容
Type\=Application Exec\=python /home/pi/faceid/main.py
树莓派GPIO图示:
a. 摄像头
camera+rpi.png
b. 超声波传感器
c. 继电器
4引脚侧 接 树莓派GPIO引脚
3端口侧 接 电磁锁
完成上述工做后,接电启动系统,本地反馈查看显示屏,云端识别结果可查看系统日志。
# 监测鉴权进程\-主进程 获取应用配置(API ID/Key 等) 初始化GPIO引脚(准备控制 传感器、继电器) 启动视频管理进程(辅进程) 循环开始: if not 测距达到触发标准: continue 与辅进程通讯(捕获当前帧,并存入指定路径,并添加“认证中”水印) 调用云API,使用该帧图片人脸识别 if 识别成功: 与辅进程通讯(变动水印为“认证成功”) 等待5秒 关机 或 继续运行(由config.json中 su2halt 字段指定) else: 与辅进程通讯(变动水印为“认证失败”) 等待2秒 与辅进程通讯(清除水印) # 视频管理进程\-辅进程 初始化摄像头 循环开始: 取帧 取进程间共享队列 按消息进行不一样操做(帧图像保存/加不一样水印/不处理) 输出帧
a. 实时视频
如上文伪代码所示,经过逐帧处理,并连续输出,显示实时视频。
b. 触发识别
测距传感器确认物体靠近,且0.3秒内距离变化小于2cm,确认为待认证状态。再延时0.3秒,进行图像帧捕获。再次延时的缘由是物体中止时,会有扭转、微调等动做,若直接取帧,会因为采光不足(上文提到的约束)出现模糊状况,因此再次延时,确保捕获稳定图像。
c. 人脸识别
请参考文档介绍
a. 水印原理
opencv中,提供了多种图像处理函数,如:图文处理(图加字)、图图处理(图间加/减/乘/除/位运算)等等。经过不一样的处理方式,能够实现 底图加字、底图加图、掩膜处理等等多种效果。本案例中使用的是基于位运算的掩膜处理方式。
b. 水印图片
为了便于维护和更新,本案例中使用图片作为水印来源,避免字库约束,也增大了灵活性,易于在水印中增长图形,并以分辨率直接定义水印大小,所见即所得。
默认水印图片为白底黑字。
c. 水印处理逻辑
为突出水印的浮动效果,将水印图片中的黑色区域透明化后,叠加到原始图片中。因为字体透明效果,水印字体颜色随基础视频变化,效果比较明显。
源码说明
# img1为当前视频帧(底图),img2为已读取水印图
def addpic(img1,img2):
# 关注区域ROI\-取底图中将被水印图编辑的图像 rows, cols \= img2.shape\[:2\] roi \= img1\[:rows, :cols\] # 图片灰化\-避免水印图非纯黑纯白状况 img2gray \= cv2.cvtColor(img2, cv2.COLOR\_BGR2GRAY) # 生成掩膜\-过滤浅色,位运算取非 ret, mask \= cv2.threshold(img2gray, 220, 255, 3) #cv2.THRESH\_BINARY mask\_inv \= cv2.bitwise\_not(mask) # 生成水印区图像\-底图裁出字体部分,生成水印区最终图像,替换原图水印区 img1\_bg \= cv2.bitwise\_and(roi, roi, mask\=mask\_inv) dst \= cv2.add(img1\_bg, img2) img1\[:rows, :cols\] \= dst return img1
水印效果示意图(示意图扩大了水印区,用于突出效果,实际应用方案中水印区较小)
示意图.jpg
a. 超声波测距
超声波传感器(4引脚:VCC、Trig、Echo、GND),Trig端输出一个大于10μs的高电平,激活发出超声波,并在收到反射波后,Echo端会输出一个持续高电平,持续时间就是“发波至收波”的时间。
即:测距结果(米)=Echo端高电平时长*340米/2
b. 继电器
使用的5V继电器模块有双侧接线,一侧为供电与信号(4引脚,兼容3.3V信号),一侧为通路开闭管理(3端口)。
继电器在“通路管理侧”实现了一个“单刀双开关”的模式,经过“供电与信号”侧“CH1引脚”的高低电平,控制单刀的方向。
在安装过程当中,电磁锁供电默认接继电器常闭端,对继电器给出信号后,继电器切换到常开端,则电磁锁断电开锁.
c. GPIO
GPIO(General-purpose input/output 通用输入输出),以引脚方式提供硬件间的联系能力。树莓派 3B+,有40个GPIO引脚(请参考上文硬件接线 中的参考图示),树莓派官方操做系统 Raspbian 下,可使用系统默认安装的 python 中 RPi.GPIO 库,进行操做。
设计的核心在于人脸鉴权模块,这里直接影响成本和稳定性,最后选择了上文方案(平衡成本、维护性及可靠性)。曾经的其它几种备选人脸识别方案:
使用ESP-EYE芯片,均由芯片完成,依赖ESP-IDF、ESP—WHO,使用C进行开发。
低硬件成本(模块成本189*2),高开发维护成本(C开发)。
问题:难于更新配置与故障分析处理。适用于大量部署场景。
使用树莓派直接进行人脸识别,方案成熟,开源代码丰富。
中硬件成本,低开发成本,高维护成本。
问题:树莓派负载高,即便用间隔帧算法,也仅维持在20fps如下,卡顿明显。如进一步调优,受限于我的经验问题,恐难以保持长期稳定运行。
使用 BM1880边缘计算开发板 或其它图像处理板,社区口碑不错,有框架支持。
问题:高硬件成本(模块成本1000*2),高开发维护成本(C开发)。若是使用算力棒,须要X86_64作基础平台,成本下降有限,复杂度不变。适用于扩展能力场景。
使用腾讯云的视频智能分析产品,简化终端架构,使用树莓派zero推流上云(后续放出实现方案),便可获取识别结果,且支持高频屡次检索等特性。
部署成本低(终端视频相关模块150元),运营成本低(当前0.28元/分钟,按该场景下单次运行20分钟计算,单次游戏成本5.6元)
问题:对网络稳定性依赖大,断流等状况影响体验。在本案例的网络约束下,影响使用效果,更适于网络条件较好、高频检索的应用场景。