基于人脸识别模型 face_recognition 实现的图片分类功能

本文尝试在 ubuntu 上跑一个人脸识别模型 face_recognition

使用 lsb_release -a命令以查看 ubuntu 的版本

1. 安装 python 以及 dlib

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

如果你安装完编译时遇到了问题,可能是缺少编译必要的依赖项,可以试着安装它们: sudo apt install build-essential cmake libopenblas-dev libopencv-dev libboost-all-dev

1.3 确认 cmake 存在
  1. 使用 cmake --version 来查看 cmake 版本,如果没有使用 sudo apt install cmake 即可

2. 安装环境所需依赖

1. 安装 face_recognition

使用 sudo pip3 install face_recognition

3. 开始使用

1. 创建文件夹并开始使用第一个命令
  1. 创建一个训练集 known_people 文件夹和一个测试集 unknown_pictrue 文件夹
  2. 此时就可以尝试用命令来跑一下试试了 face_recognition known_people/ unknown_pictures/
  3. 如果 known_people 文件及下存在无法识别为人脸的图片,会抛出错误,不过无所谓。还有一点要注意一下,不要放旋转的照片进去,因为有可能识别不到
  4. 程序输出了一些内容
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. 使用额外的参数来进行微调
  1. --tolerance 默认容差值为 0.6,较低的数字使面部比较更加严格。通过上一步的输出,我意识到有些照片程序检测的太敏感了,比如 4.jpg 检测到了3个人,其实只有2个,此时可以使用该参数逐渐调低容差尝试,不过如果太低,会识别成 unknown_person,我使用下面命令 face_recognition --tolerance 0.52 known_people/ unknown_pictures/ > data.txt
  2. --show-distance 如果您想查看为每个匹配计算的人脸距离以调整容差设置,可以使用face_recognition --show-distance true ./pictures_of_people_i_know/ ./unknown_pictures/
  3. --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 目录,目录里是人物的文件夹,文件夹内是人物的照片

具体的目录可以参考下图

相关推荐
Dontla24 分钟前
HTTP查询参数示例(XMLHttpRequest查询参数)(带查询参数的HTTP接口示例——以python flask接口为例)flask查询接口
python·http·flask
人类群星闪耀时27 分钟前
破解 N 皇后 II:位运算的高效艺术
python·算法·数学建模
最强菜鸟27 分钟前
python爬虫爬取淘宝热销(热门)零食商品加数据清洗、销量、店铺及词云数据分析_源码及相关说明文档;售后可私博主
爬虫·python·数据分析
啊阿狸不会拉杆1 小时前
第二十五章:Python-pyecharts 库实现 3D 地图绘制
开发语言·python·地图
满怀10151 小时前
Python入门(8):文件
开发语言·python
pk_xz1234561 小时前
完整的Python程序,它能够根据两个Excel表格(假设在同一个Excel文件的不同sheet中)中的历史数据来预测未来G列数字
开发语言·python·excel
程序员一诺1 小时前
【Flask开发】嘿马文学web完整flask项目第2篇:2.用户认证,Json Web Token(JWT)【附代码文档】
后端·python·flask·框架
搬砖的阿wei2 小时前
Matplotlib:数据可视化的艺术与科学
python·信息可视化·matplotlib