分类目录: 软件应用

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

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

架构图:
image

代码和部署使用方法在如下git工程:https://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应该有正统的输出人脸的质量的参数,查了很久,没有找到合适的方法,就只能先这样吧。在比对方面,还有一些重要的概念,没有弄明白,如人脸对齐、年龄、性别检测等,不清楚我的代码里面是否已经有调用已经做了这块。

具体的处理代码:

01data = np.frombuffer(data, np.uint8)
02if data is None:
03    raise Exception('image is required.')
04 
05zoom_ratio = 1
06if data.size > 6 * 1024 * 1024:
07    img = cv2.imdecode(data, cv2.IMREAD_REDUCED_COLOR_4)
08    zoom_ratio = 4
09elif data.size > 4 * 1024 * 124:
10    img = cv2.imdecode(data, cv2.IMREAD_REDUCED_COLOR_2)
11    zoom_ratio = 2
12else:
13    img = cv2.imdecode(data, cv2.IMREAD_COLOR)
14 
15faces = []
16dets = detector(img, 1)

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

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

docker本地安装tiny tiny rss记录

01# 启动mariadb 10.0.38
02docker run --name mariadb -p 3306:3306 \
03-e MYSQL_ROOT_PASSWORD='password' \
04-d mariadb:10.0.38
05 
06# 安装docker php 5.6
07docker run -p 9000:9000 --name php \
08-v /opt/codefine.site/:/opt/codefine.site/ \
09-v /opt/codefine:/opt/codefine \
10-v /media/c2/php//conf:/usr/local/etc/php \
11-v /media/c2/php/logs:/phplogs \
12-v /opt/phpmyadmin:/opt/phpmyadmin  \
13-d php6:latest
14 
15# 安装php插件。借助于内部家里的内部梯子。懒得设置debian镜像。
16export http_proxy=http://22.22.22.14:10080
17apt update
18apt install libxml2-dev
19apt install libxml2
20apt install libcurl3
21apt install libcurl4-gnutls-dev
22ln -s x86_64-linux-gnu/curl curl
23apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev
24 
25docker-php-ext-configure gd --with-freetype --with-jpeg
26docker-php-ext-install -j$(nproc) gd
27docker-php-ext-install mysql
28docker-php-ext-install mysqli
29docker-php-ext-install intl
30docker-php-ext-install pdo
31docker-php-ext-install pdo_mysql
32docker-php-ext-install fileinfo
33docker-php-ext-install xml
34docker-php-ext-install mbstring
35docker-php-ext-install json
36docker-php-ext-install opcache
37 
38docker-php-ext-enable intl
39docker-php-ext-enable pdo
40docker-php-ext-enable pdo_mysql
41docker-php-ext-enable fileinfo
42docker-php-ext-enable xml
43docker-php-ext-enable mbstring
44docker-php-ext-enable json
45docker-php-ext-enable opcache
46docker-php-ext-enable mysql
47docker-php-ext-enable mysqli
48docker-php-ext-enable gd
49 
50# 生成新的镜像。
51docker save -o php.tar php
52docker load -i php.tar
53# 重新run一个新的container。
54 
55# nginx
56cat /etc/nginx/sites-enabled/ttrss
57server {
58    listen 12345 ssl;
59    root /opt/codefine.site/;
60    index index.php index.html index.htm;
61    server_name photo.codefine.site;
62    ssl_certificate     /path/of/server/file.pem;
63    ssl_certificate_key /path/of/server/key/file.pem;
64    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
65 
66    location / {
67        try_files $uri $uri/ =404;
68    }
69 
70    location ~ \.php$ {
71        include snippets/fastcgi-php.conf;
72        fastcgi_pass   127.0.0.1:9000;
73    }
74}
| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:移动互联, 软件技术 | 标签: , , , |

Ubuntu 20.04桌面体验

对于Ubuntu桌面的印象还停留在很多年前,当年的感觉是,比较容易崩溃,需要修改配置文件的地方太多,一不小心系统就崩溃了。家里近10年前的笔记本,几次操作系统自动升级后,已经变得一打开Win10系统就开始呼呼叫。像是一个年迈的老人,稍微快步走路就气喘一样。想试一下最新的Ubuntu,装系统很容易,直接下载镜像,写入U盘,制作成启动盘,引导安装。最可贵的是,居然自动识别老的Win10系统,做成了双系统,需要的时候还能进入Win10。用了几天,感觉Gnome桌面的整体风格跟Mac越来越像了,几乎不需要手动修改配置。自动发现U盘、界面连接Wifi、安装软件等体验都不错。其实日常家里使用笔记本也就是看看文档、浏览网页、看看开源代码,还有一些常用的社交应用的网页版,无缝访问家里的NAS系统。Ubuntu生态里面,离完全满足这些应用还有距离,但是在性能体验上面,已经远远超出Windows了,特别是硬件资源不足的情况。生态欠缺也是硬伤,如:微信微博等没有linux版本客户端,没有一些通用的轻量级代码编辑器:Nodepad++和VSCode等。好在现在越来越多的东西都可以在Web页面上解决。

阅读全文 »

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

分享一个树莓派延时摄影和视频制作代码

心血来潮,想着做一个阳台花草生长的延时视频。阳台上正好有个树莓派,只需要一个摄像头即可。说做就做,500万像素的树莓派摄像头,包邮只需要30元。基本够够用了。接好线,固定好摄像头位置。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 同时归档在:实用脚本, 数码硬件 | 标签: , , , |

使用ffmpeg工具转换mov、avi格式为mp4

iPhone拍摄的视频备份到Home-NAS后,文件类型是mov,无法在网页上直接呈现,因此需要对视频编码进行转换。本想找一个批量转换的工具。无奈,从几个下载网站上面找了多款工具都不能完美实现,要么需要购买,要么转换后的视频效果极差。考虑使用ffmpeg工具,直接使用命令行转换,最终使用如下脚本实现了格式转换和元数据信息的拷贝。

set indir=%1

for %%a in (%indir%\*.mov) do ffmpeg -i "%%a" -map_metadata:s:a 0:s:a -map_metadata 0:g -map_metadata:s:v 0:s:v -vcodec copy -acodec copy "%%a.mp4"

for %%b in (%indir%\*.avi) do ffmpeg -i "%%b" -map_metadata:s:a 0:s:a -map_metadata 0:g -map_metadata:s:v 0:s:v -vcodec copy -acodec copy "%%b.mp4"

将如上代码保存为bat文件,将存放有mov和avi格式文件的目录拖拽到bat文件上面执行即可实现转换。

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

Google Project Zero成员谈如何入门安全工作

已经有很多人(包括我谷歌的同事,ParisaMichal已经就这个话题写过自己的感受,我建议你仔细阅读。我知道我写的这些可能已经有人说过了,但是每隔一段时间,我总是会再次遇到这个问题,于是我决定写下自己的经验。

首先,我是一个应用安全研究员,我是从 漏洞研究/安全审查/bug寻找/黑客攻击 等角度来阐述安全入门的。在安全领域还有很多其他的方向,比如安全研发,恶意软件分析等等,这些我并不熟悉。

那么,我是谁?为什么你要在这个话题上信任我呢?嗯,首先我不是说你应该完全信任我,因为每个人的经验和每个人的道路都是有所不同的。但如果您对我感到好奇,我可以告诉您,我现在是 Google Project Zero 的成员,我曾经是谷歌安全团队的成员,是多个安全工具的作者多个安全工具的作者,如果你在这个博客上滚动足够长的时间,你会发现我已经从事安全工作十多年了。

我认识的安全研究员来自很多不同的背景,但是我的背景有所不同,我有相当强的学术背景,这在我的同行中是非常不典型的,当然这并不是进入安全领域的要求。然而,我所知道的安全研究员中的大多数人都有一些共同点,这里我们来看第一条:

阅读全文 »

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

给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 ... | 同时归档在:WEB网络, 软件技术 | 标签: , , |