V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
novato
V2EX  ›  分享创造

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

  •  
  •   novato · 2019-10-06 20:01:21 +08:00 · 3946 次点击
    这是一个创建于 1900 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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