两年前公司说有个项目要搞“刷脸过闸”,开始大家都不知怎么搞,我就到网上查了一下,开始查到一个openface,一个 python 库,我就用 flask+flask_socketio 将之封装成一个 docker 镜像 run 在服务器上,然后各个闸机通过 socket.io 连接(每个闸机上有个 nodejs 服务)把页面中通过 getUserMedia 抓取的图像发到服务器上去比较。
我想当然的认为这个流程应该是:游客在自助机上买票时,刷脸进行下一步选票,扫码付款成功后,自助机把人脸照片发到后台去提取特征值存数据库,每台闸机每两秒(或界面上有个按钮触发)抓张照片发到后台去,与已付款但是还未入园的游客特征比较,如果某个匹配则通知闸机开闸,并改数据库状态标记该游客已消费。然后写了个 demo 测试发现效果还行。因为公司里搞硬件的就我一个,我就自己想当然的瞎搞。
后来又发现有个这个项目face_recognition,也是个 python 库,但是封装的更好,觉得以前的很多都白做了。但是有个问题,每台闸机都发照片去后台提取特征 /比较,这个操作是很耗时的,如果闸机多的话会搞的服务器压力很大。为什么不在本地提取特征,然后购票成功的游客特征通过服务器广播到每台闸机,那么人脸比较在本地进行就好了,匹配成功后开闸 and 通知服务器改状态。
因为闸机上已经有个 nodejs 服务了,nwjs 做界面,通过 socket.io 与本地 nodejs 交互操作硬件(下面有个 nodejs 接硬件的文档),本地 node 再通过 Websocket 与后台交互进行支付等操作。那么我想干嘛不能让本地 nodejs 直接提供人脸特征 提取 /比较 服务?我看上面那个face_recognition是封装 dlib 的,dlib 是个 C++库,C++写 nodejs 插件再合适不过了。
然后我一拍脑袋就把 boost+opencv+dlib 写成了一个 nodejs 插件,其实 boost 没怎么用到,只是用了其中的 log 库,整合进去留作以后备用吧。顺便把 tts 也加进去吧,因为闸机 /自助机经常要语音播报的。nodejs 用 express 把 C++写的功能用 restful 服务呈现出来,再用 pkg 打包成可执行文件,双击运行后,用浏览器打开本地链接 http://localhost:12345 就可以使用了,接口说明及 jquery's ajax 调用方式请参考其中的例子代码。
这东西写好后,公司那个项目后面又没做了,因为这只是我个人瞎搞的,而且现在已离职了,就发出来给感兴趣的参考下吧。
git 库:
https://github.com/novice79/node_face
因为这个 C++代码编译比较麻烦,可以下载这个编译好的(里面的人脸模型比较大,100 多兆),解压后直接双击运行即可。
人脸比较服务 Demo
github 上下载太慢,再加个
网盘分享
后记:后面发现别人根本就不是这个流程,而是先刷身份证,获取身份证上的照片再与摄像头拍摄的比较,可能他们觉得人脸比较不能 100%可靠,还需要身份证号验证吧。
附:之前写的一个文档:
[nodejs 对接硬件.doc]( https://novice79.github.io/doc/nodejs 对接硬件.doc)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.