尝试写了一个人脸比较服务 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
novato
V2EX    分享创造

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

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

    两年前公司说有个项目要搞“刷脸过闸”,开始大家都不知怎么搞,我就到网上查了一下,开始查到一个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 是两种场景
    benson458
        3
    benson458  
       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     Solana     1347 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 17:07 PVG 01:07 LAX 09:07 JFK 12:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86