由于新一届的物联网大赛有关于人脸识别的部分,因此老师让我给学弟学妹讲一讲有关人脸识别的部分。因为上次刷知乎的时候看到了一个圣诞节时的微信头像自动带圣诞帽的小程序用到了这个 face_recognition 的 Python 库,上网查了一下,发现离线识别率高达99.38%,因此就打算使用这个库了。
理想很丰满,现实很骨感。折腾了很长时间,不由得感叹,这个库是真 TMD 难配。
以下就是记录的一些过程吧!
配置和安装
需要的诸如 numpy、opencv 等的机器学习的常用库就不写了,这些不难,而且我早已配过了。重点是安装 dlib.
本次的配置基本参考face_recognition的 readme
需求:
- Python 3.3+ or Python 2.7
- macOS or Linux (Windows not officially supported, but might work)
这里我使用的环境就是 Python3.6 + macOS,(作者已经说了,Windows 环境下没有测试,而且我看了网上好像 Windows 确实各种坑,所以小伙伴们还是不要去跳坑了吧,老老实实 Linux 吧)
安装 dlib
作者有给连接指导怎样安装 dlib 的,How to install dlib from source on macOS or Ubuntu,但是这个网址被墙了,可以科学上网的同学就直接去看。
为了帮助无法科学上网的同学,我把 dlib 安装指导 copy 了过来:
前置工作:
For macOS
- 安装 XCode (主要是 XCode command line utils)
- 安装 homebrew
brew install boost-python --with-python3 --without-python
For Linux
sudo apt-get install libboost-all-dev
安装:
- clone the code from github
git clone https://github.com/davisking/dlib.git
- build the main dlib library
cd dlib
mkdir build; cd build; cmake .. -DDLIB_USE_CUDA=0 -DUSE_AVZ_INSTRUCTIONS=1; cmake --build
- build and install the python extensions
cd ..
python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA
安装 face_recognition
这个就没什么好说的了,pip3 install face_recognition
测试
如果你进入 Python3,可以成功 import dlib
,就表示你的 dlib 成功安装了
如果你在 terminal 内输入 face_
,按 tab 键,能够自动补全 face_recognition 说明 face_recognition 已经成功安装了
备注
作者提供了一个 virtualBox 的 Ubuntu 镜像,内部已经配置好了一切的环境,如果有需要可以点这里下载
直接使用
前面在 terminal 里面,face_recognition 就已经可以直接使用了,具体的做法是:
1 | face_recognition 已知人物照片的目录 需要识别的照片目录 |
还可以加入一些参数,比如容忍度 --tolerance
,越小的容忍度,则识别时就越严格
加入 --show-distance true
可以显示两个人脸的差距,用于调整容忍度
代码
前面的是直接使用 face_recognition
这个命令的,当然也可以在 Python 里面 import 这个库,做其他的处理
我在使用库的时候遇到了 No module named 'face_recognition'
的问题,如果你也遇到了这个问题,并且你确定你在输入 pip3 list
后,face_recognition 这个库确实已经安装完成了。那么你可以在代码中加入下面两句以引用 face_recognition
1 | import sys |
在添加了正确的路径之后,就可以正确的 import 这个包了(每个人的 site-packages 的位置不一定一样)
面部定位
1 | image = face_recognition.load_image_file("./pic/obm2.jpg") |
首先使用 load_image_file 函数将需要识别的图片添加进去,再调用 face_locations 函数就可以返回面部的坐标,如下:
1 | [(1268, 2884, 1423, 2729), (1062, 2248, 1216, 2093), (1142, 2575, 1271, 2446), (1200, 1543, 1329, 1414), (1295, 3111, 1481, 2925), (1062, 2764, 1216, 2609), (1027, 3482, 1212, 3296), (1013, 1199, 1142, 1070), (1148, 1336, 1302, 1182), (1182, 1044, 1337, 889), (956, 1629, 1085, 1500), (1212, 778, 1398, 593), (1062, 1869, 1216, 1715), (956, 2532, 1085, 2403), (1406, 3510, 1628, 3287)] |
其中,每一个脸部位置坐标是由4个数字的元组组成的,其分别为 $ x_1 , y_1 , x_2 , y_2 $ ,这两个点分别是确定脸部位置的两角,可以用 OpenCV 加载图片,并且使用切片操作截取脸部
1 | index = 0 |
面部比较
- 加载已知的头像
1 | dt_image = face_recognition.load_image_file("./head/dt_1.jpg") |
- 加载待识别的头像
1 | unknown_image_1 = face_recognition.load_image_file("./unknow_head/unknow_1.jpg") |
- 编码
1 | dt_encoding = face_recognition.face_encodings(dt_image)[0] |
- 输入结果
1 | results = face_recognition.compare_faces([dt_encoding, sll_encoding, obm_encoding], unknown_encoding[i]) |
输出的结果是一个3个的 list,内部的值分别是 true 或者 false 表示是不是对应的人