基于人脸识别模型 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 目录,目录里是人物的文件夹,文件夹内是人物的照片

具体的目录可以参考下图

相关推荐
一颗星星辰3 分钟前
Python | 第九章 | 排序和查找
服务器·网络·python
打码人的日常分享4 分钟前
企业人力资源管理,人事档案管理,绩效考核,五险一金,招聘培训,薪酬管理一体化管理系统(源码)
java·数据库·python·需求分析·规格说明书
27669582924 分钟前
京东e卡滑块 分析
java·javascript·python·node.js·go·滑块·京东
unix2linux4 分钟前
Parade Series - SHA256
linux·python·mysql·shell
巽星石33 分钟前
【Blender Python】7.一些运算、三角函数以及随机
python·blender·三角函数·随机·环形阵列
CSXB9933 分钟前
一、Python(介绍、环境搭建)
开发语言·python·测试工具·集成测试
Mopes__37 分钟前
Python | Leetcode Python题解之第461题汉明距离
python·leetcode·题解
EterNity_TiMe_1 小时前
【机器学习】智驭未来:探索机器学习在食品生产中的革新之路
人工智能·python·机器学习·性能优化·学习方法
Mopes__2 小时前
Python | Leetcode Python题解之第452题用最少数量的箭引爆气球
python·leetcode·题解
AI视觉网奇2 小时前
pymeshlab 学习笔记
开发语言·python