分类目录: WEB网络

基于Dlib、Flask和Sqlite的人脸检测和识别服务

这个十一原定的计划取消了,没有做好备份计划,也就不打算出远门了,关在家里,把一直都想做的一个本地化的人脸识别服务整了一下。提供人脸分析的开源服务似乎很多年都没有大的变化了,一直都是Dlib和OpenCV,对比了一下,Dlib更容易使用。一直没有正经写过Python代码,翻出N年前买的Python编程书,边翻书Google、边写代码。基本的代码流程比较简单,Dlib官方也有例子,很容易运行起来,但是要服务化,要做人脸比对,并且是增量的人脸比对和识别,并不容易。说做就做,最终整个服务形成如下架构。

架构图:
image

代码和部署使用方法在如下git工程:http://git.codefine.site:3000/Shentar/facerec

首先需要将探测的过的“人脸”存储起来,然后能输入一张人脸返回与该人脸近似的所有人脸,这样客户端好做人脸归集。很快做好了一个初步的框架:使用Flask提供REST接口接收照片,在响应中返回人脸的特征标识,使用SHA256对人脸68点位的描述向量进行HASH,返回给客户端。同时将HASH值和实际的token存储到Sqlite。第一天大概就完工了这个功能。

运行起来,发现单纯的Flask不能并发,第二个请求会报错,一次只能接受和处理一个请求。于是又按照网上的经验,使用Gunicorn和Gevent来做多线程的方案,因为习惯了单进程多线程的方式,多线程访问Sqlite需要加锁,按照通用的做法,使用一个队列来管理Sqlite实例。继续验证,发现多线程并不能加速Detect的效率,貌似Dlib不支持多线程加速。调整为多进程,四个CPU都能运用起来。

1d2dd2b5bcde40b6a563996821d84843

终于找到了一个能将这个3.2GHZ的四核CPU跑满的业务了 ^_^

Architecture: x86_64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
Address sizes:                   39 bits physical, 48 bits virtual
CPU(s):                          4
On-line CPU(s) list:             0-3
Thread(s) per core:              2
Core(s) per socket:              2
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       GenuineIntel
CPU family:                      6
Model:                           94
Model name:                      Intel(R) Core(TM) i3-6100T CPU @ 3.20GHz

人脸检测的效果还不错,错误率的话,自己家用是够了。特别是在侧脸检测上面,比较准确。在人脸比对方面,错误率就要高一些了,反复验证,发现0.36的比对阀值比较合适。侧脸虽然检测率高,但是在比对上面,只用通用的拟合范数,结果会表现为差异很大。因此这里应该是需要有定制化的比对实现,只做部分比对。这块需要深入到人脸检测技术内部,去分析128D的特征值向量的每一个值,短时间内没办法去研究透了。

由于采用了多进程,因此没法共用一个Sqlite运行时实例,强行并发读写访问会导致数据库错乱,不得不又做了一个服务来封装Sqlite,多个检测进程输出的人脸特征值都发给该服务来顺序存储,同时也返回给客户端。两个服务之间同样采用REST接口交互。

准备大规模上量,将jAlbum目前使用的线上人脸识别服务切换到这个本地服务上面,又发现检测时长非常高,一张4M的图片,大概需要几秒的时间,并且还有些非常小的区块被检测到了。对于检测慢的问题,考虑降低输入的照片的像素,图片减小后,长宽的像素点都相应减少了,但是人脸的特征点并不会损失太多。因此先对图片进行降低像素和尺寸,识别完成后,对识别到的人脸在照片上的位置也要相应做缩放,对比了一下,原始大小检测和缩放后检测,再对结果做相反的缩放,最终结果误差不大,但是这样能极大提速。对于非人脸和质量不高的人脸被检测到的问题,做了一些粗浅的限制,人脸长宽必须大于100的阀值才认为是正常的人脸。Dlib应该有正统的输出人脸的质量的参数,查了很久,没有找到合适的方法,就只能先这样吧。在比对方面,还有一些重要的概念,没有弄明白,如人脸对齐、年龄、性别检测等,不清楚我的代码里面是否已经有调用已经做了这块。

具体的处理代码:

data = np.frombuffer(data, np.uint8) 
if data is None: 
    raise Exception('image is required.') 

zoom_ratio = 1 
if data.size > 6 * 1024 * 1024: 
    img = cv2.imdecode(data, cv2.IMREAD_REDUCED_COLOR_4) 
    zoom_ratio = 4 
elif data.size > 4 * 1024 * 124: 
    img = cv2.imdecode(data, cv2.IMREAD_REDUCED_COLOR_2) 
    zoom_ratio = 2 
else: 
    img = cv2.imdecode(data, cv2.IMREAD_COLOR) 

faces = [] 
dets = detector(img, 1)

总的来说,开源项目,适合做一下Demo,如果要尽善尽美,那么就要深入到源码,有针对性的去优化检测和比对模型。作为个人的实验和家用还是很不错的。至少在快速编程和服务化这方面。

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 同时归档在:数码硬件, 架构设计, 移动互联, 软件应用 | 标签: , , , , , |

记一次WordPress手动升级

本站用的Wordpress版本(4.8.2)有些老了。从主程序的代码记录来看上一次升级还是17年的事情,快三年了。

image

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 同时归档在:建站技术 | 标签: , , , , |

Home NAS上可以运行哪些有趣的服务?

一、jAlbum

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 同时归档在:建站技术, 数码硬件, 移动互联 | 标签: , , , , , , , , |

使用let’s encrypt制作免费HTTPS证书

在外网访问家里的NAS服务器上面的jAlbum相册时,使用HTTPS更安全。之前使用的一直是自签发的证书,在自己的手机上面导入了自签发证书的CA,因此浏览器一直显示安全的绿色。今天在其他手机上面使用HTTPS访问时,打不开页面,使用HTTP访问则没问题,很快就想到这是证书的问题,自签发证书的根证书没有安装。但是总不能每次有新的设备访问时就要求其安装CA证书,除非这个服务能做到像12306那么不可或缺(12306上线很多年都不购买商用证书,一直要求用户下载证书安装到本地,这种做法很危险)。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 同时归档在:建站技术 | 标签: , , , , , |

记录一下最近修改的两个Bug

最近改了两个jAlbum的bug,问题并不复杂,但是比较有代表性。在这里记录一下。第一个问题是,在单张照片的页面提供了一个“隐藏”当前照片的按钮。当点击该按钮时,页面重新load,显示下一张照片,使用了当前照片的ID来构造下一张照片的url,即加载url:
/?next=[currentphotoid]&count=1,
具体到服务端接收这个请求时,需要使用当前照片的ID到数据库中索引下一张。
然后对当前照片发起删除操作,即使用ajax发起一个HTTP请求:
DELETE /photos/[currentphotoid]
向服务端发送一个delete请求,具体的浏览器端代码为:

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 同时归档在:Java, 多线程编程 | 标签: , , , |

给CSDN极客和开发者头条增加RSS源

CSDN极客,网址:http://geek.csdn.net/,经常有一些比较好的链接,对于程序员来说,有一些阅读学习价值。不知从何时开始该网站不再提供RSS订阅,这对于RSS重度使用者来说有点难以忍受。因此花了一下午时间做了一个抓取该网站头条主页内容生成RSS订阅地址的实现。使用PHP后台抓取网页内容,对内容进行正则匹配后过滤出有价值的链接,生成RSS XML格式文档后返回。订阅地址为:http://codefine.site/rss_factory?url=geek.csdn.net。同样,也给支持开发者头条(https://toutiao.io)新增了RSS源:http://codefine.site/rss_factory?url=toutiao.io

订阅效果:

CSDN极客订阅

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 4票) Loading ... Loading ... | 同时归档在:软件应用, 软件技术 | 标签: , , |

Linux TCP Backlog机制分析

前一阵子遇到一个奇怪的问题,分析了很久,最后查阅了一些资料,找到了问题的原因,是TCP的backlog机制的原因。首先描述一下重现问题的现象和过程: 构建一个TCP的服务端,监听端口4321,只监听请求,不accept,客户端不断发起连接,观察TCP连接建立的情况。服务端程序代码如下:

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 同时归档在:IO编程, Linux内核, 算法数据结构 | 标签: , , |

家用NAS组网

不满足于之前的树莓派搭建的HOME NAS,又折腾了一套X86的低功耗版NAS服务器,将之前放在硬盘盒里面的硬盘都规整到了NAS服务器内。直接安装Windows Server 2012版本,配置简单。

不断增加网络设备,突然发现家里的网络越来越复杂,首先把家里的网络设备连接图整理出来记录一下。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 5票) Loading ... Loading ... | 同时归档在:数码硬件, 移动互联 | 标签: , , |

jAlbum 0.1.6版本截图

新增主要功能:修改页面适配手机屏幕。

Android 手机截图效果:

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 15票) Loading ... Loading ... | 同时归档在:Java, Jetty, 移动互联, 软件技术 | 标签: , |

开源照片整理系统jAlbum 0.1.3版本发布

第三个版本,jAlbum完整版差不多完工了:https://github.com/shentar/jAlbum/releases/tag/jAlbum_0.1.3

最后解决了文件系统监控的问题。利用Java1.7封装的文件系统的通知回调机制,实现对指定目录的递归监控,避免每次全盘扫描性能太低的问题。

注意对于linux系统对于单个用户能够监听的inotify对象个数做了限制,一般是限制为8192,因此需要修改系统内核的配置:在/etc/sysctl.conf文件中,新增一行:fs.inotify.max_user_watches=1000000,表明将该限制修改为100万个。下次重启后会生效,如果希望当前立即生效,则需要执行命令:sysctl –p 。

对于WatchService,只监控当前目录的变化,当前目录下新增文件或者文件夹时,当前文件夹会有修改事件或者创建事件,但是再下一层的文件夹或者文件发生变更时,并不会有任何事件,因此如果要监控指定的文件夹,需要递归监控到最后一层。没有验证文件系统的notify机制对进程性能和文件系统性能的影响,在树莓派上面简单验证了下,能够非常及时的发现新增文件,进程CPU和内存也没有明显的增加。终于解决了每次都有依赖全盘扫描一遍文件才能发现新增的文件的问题。

具体代码请参见源码中的DirWatchService类。

| 1 分2 分3 分4 分5 分 (5.00- 9票) Loading ... Loading ... | 同时归档在:Java, Jetty, 数据库, 软件技术 | 标签: , , |
返回顶部