尝试写了一个人脸比较服务

2019-10-06 20:01:21 +08:00
 novato

两年前公司说有个项目要搞“刷脸过闸”,开始大家都不知怎么搞,我就到网上查了一下,开始查到一个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)

3926 次点击
所在节点    分享创造
8 条回复
novato
2019-10-06 20:13:56 +08:00
本来要点预览的,结果点成发布了。
最后那个文档链接是没空格的:
https://novice79.github.io/doc/nodejs 对接硬件.doc
ila
2019-10-06 20:24:03 +08:00
1:1 和 1:n 是两种场景
wbing
2019-10-06 21:41:17 +08:00
通过身份证那直接是 1:1 进行比对的,你做的那是 1:n。
你把购票成功的游客特征通过服务器广播到每台闸机,每台闸机都会存储一个完整的人脸特征库,闸机既要进行特征提取又要做人脸比对的,这样就是当游客数量很多的时候,对闸机性能要求也挺高的。
如果闸机只做特征提取,服务器只做特征比对,闸机只要将提取到的特征值发送给服务器比对下特征值然后返回,是不是效果会更好?
sadfQED2
2019-10-06 23:17:17 +08:00
我毕业设计就做的人脸比较,用 VGG 网络,在全连接层输出降维,然后求两个人脸图片的余弦值,余弦越大,相似度越好,但是没解决的就是 1: n 的时候只有遍历,性能太差,做到毕业也没想出索性怎么做
kajweb
2019-10-07 03:55:51 +08:00
身份证照片与本人匹配匹配一致性会不会存在问题……毕竟 SFZ 采集的时候各种标准不一致,还有化妆,还有其他各种问题……emmm,这里好像偏离了 LZ 的主题了,只是顺便问一下。
novato
2019-10-07 09:05:36 +08:00
@wbing 你说的方案挺好,只是前 /后台都要运行同一套人脸系统,服务器一般是 Linux,后面我再把它编译一个 Linux 版的再做个镜像。另外 1:n 的好像并没有运行在哪个涉及支付的系统上把?比如 机场、高铁、或哪个 5A 景区,都是要刷身份证的。可能只有类似考勤机那种要求不太高的系统会用 1:n。
@kajweb 与身份证照片匹配会存在问题,其实它主要是用身份证号认证的,这个身份证读取器必须要公安部认证的模块才能读取,所以读上来的号码不会有假。加个人脸匹配只是大致确认一下:你没把身份证给别人用,或别人捡了你的身份证。
xuexiaoaoooo
2019-10-08 14:12:49 +08:00
对于亚洲人脸的对比正确率咋样呢
novato
2019-10-08 19:02:46 +08:00
@xuexiaoaoooo 跟 face_recognition 用的模型一样,它宣称是 99.38%。不管是亚洲、欧洲,只要是地球上的人类应该都可以。当然我自己没测过,这个需要大量样本的,不是个人能搞的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/606623

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX