本文尝试在 ubuntu
上跑一个人脸识别模型 face_recognition
使用
lsb_release -a
命令以查看ubuntu
的版本

1. 安装 python 以及 dlib
1.1 安装 python
- 使用
apt
安装python
大于3.3
的版本sudo apt install python3.10
- 使用
python3 --version
来检测当前安装的python
版本,如果是python 2.x
, 则使用python --version
,不过这是题外话,这个版本库明确要求python3.3
以上
1.2 安装 dlib
- 如果没有
pip
, 使用sudo apt install python3-pip
来安装,使用pip3 --version
查看pip
的版本 - 使用
sudo pip install dlib
来安装dlib

如果你安装完编译时遇到了问题,可能是缺少编译必要的依赖项,可以试着安装它们:
sudo apt install build-essential cmake libopenblas-dev libopencv-dev libboost-all-dev
1.3 确认 cmake 存在
- 使用
cmake --version
来查看cmake
版本,如果没有使用sudo apt install cmake
即可
2. 安装环境所需依赖
1. 安装 face_recognition
使用 sudo pip3 install face_recognition

3. 开始使用
1. 创建文件夹并开始使用第一个命令
- 创建一个训练集
known_people
文件夹和一个测试集unknown_pictrue
文件夹 - 此时就可以尝试用命令来跑一下试试了
face_recognition known_people/ unknown_pictures/
- 如果
known_people
文件及下存在无法识别为人脸的图片,会抛出错误,不过无所谓。还有一点要注意一下,不要放旋转的照片进去,因为有可能识别不到 - 程序输出了一些内容
shell
WARNING: No faces found in known_people/cat.png. Ignoring file.
WARNING: No faces found in known_people/certificate.jpg. Ignoring file.
WARNING: No faces found in known_people/Identification_card.jpg. Ignoring file.
WARNING: No faces found in known_people/Educational.jpg. Ignoring file.
unknown_pictures/2.jpg,lll
unknown_pictures/2.jpg,scx
unknown_pictures/2.jpg,scx
unknown_pictures/1.png,lll
unknown_pictures/4.jpg,lll
unknown_pictures/4.jpg,scx
unknown_pictures/4.jpg,scx
unknown_pictures/5.jpg,lll
unknown_pictures/5.jpg,scx
unknown_pictures/3.jpg,lll
unknown_pictures/3.jpg,scx
2. 使用额外的参数来进行微调
--tolerance
默认容差值为 0.6,较低的数字使面部比较更加严格。通过上一步的输出,我意识到有些照片程序检测的太敏感了,比如4.jpg
检测到了3个人,其实只有2个,此时可以使用该参数逐渐调低容差尝试,不过如果太低,会识别成unknown_person
,我使用下面命令face_recognition --tolerance 0.52 known_people/ unknown_pictures/ > data.txt
--show-distance
如果您想查看为每个匹配计算的人脸距离以调整容差设置,可以使用face_recognition --show-distance true ./pictures_of_people_i_know/ ./unknown_pictures/
--cpus
设置几个cpu
来跑,不过个人不推荐用这个,使用过程中遇到了有些图片读取不到的情况
3. 实现图片分类
1. 方案
因为自带的功能已经足以满足我的需要,所以方案只需要收集 face_recognition
的返回结果,结果中已经可知在哪张照片中识别出了哪个人,利用 python
脚本稍加处理,就知道如何进行图片分类了
2. 实现
执行程序,并将结果输出到一个文件中,上文开始使用的第一部分已经说明了程序输出内容
shell
face_recognition --tolerance 0.52 known_people/ unknown_pictures/ > data.txt
编写 python
程序,复制图片到对应的文件夹下即可
python
import os
import shutil
data_file = "data.txt"
result_file = "result.txt"
dist_folder = "dist"
unknown_person = 'unknown_person'
# 读取文件内容
with open(data_file, "r") as file:
lines = file.readlines()
# 处理数据并创建数组
data = []
for line in lines:
line = line.strip() # 去除行两边的空格和换行符
if line.startswith("WARNING"):
continue # 忽略以 "WARNING" 开头的行
data.append(line)
# 创建一个字典,字典 key 为图片路径,value 为图片识别到的人
my_dict = {}
for item in data:
file_path, person_name = item.split(",")
person_name = person_name.strip() # 去除人名两边的空格
if file_path not in my_dict:
my_dict[file_path] = []
if person_name not in my_dict[file_path]:
my_dict[file_path].append(person_name)
# 创建 dist 文件夹(如果不存在)
if not os.path.exists(dist_folder):
os.makedirs(dist_folder)
# 先删除不需要的结果文件
if os.path.exists(result_file):
os.remove(result_file)
# 创建结果文件
with open(result_file, "x"):
pass
hasErr = False
errMsgs = []
# 循环my_dict字典,其中键为文件路径,值为检测到的人
for file_path in my_dict:
names = my_dict[file_path]
if unknown_person in names:
hasErr = True
errMsg = f"图片 {file_path} 存在未识别出的人像,识别结果为 {names}"
errMsgs.append(errMsg)
for person_name in names:
# 创建人名对应的文件夹(如果不存在)
person_folder = os.path.join(dist_folder, person_name)
if not os.path.exists(person_folder):
os.makedirs(person_folder)
# 复制图片到对应的文件夹中
file_name = os.path.basename(file_path)
destination_path = os.path.join(person_folder, file_name)
shutil.copy(file_path, destination_path)
with open(result_file, "a") as f:
if not hasErr:
f.write("没有错误发生,图片已归类")
print("没有错误发生,图片已归类" + "\n" + "exist with code 0")
else:
print("发生错误,已将识别到的图片归类,错误详情如下")
for errMsg in errMsgs:
print(errMsg)
f.write(errMsg + "\n")
会生成一个 dist
目录,目录里是人物的文件夹,文件夹内是人物的照片
具体的目录可以参考下图
