首页 > 编程语言 >【Python】利用 face_recognition 库进行人脸检测识别【附完整示例】

【Python】利用 face_recognition 库进行人脸检测识别【附完整示例】

时间:2024-07-27 14:59:21浏览次数:18  
标签:示例 Python image face 人脸 path recognition 图片

1. 背景条件

1.1 安装所需库

首先安装 face_recognitionPillow 这两个库。您可以使用以下命令来安装它们:

pip install face_recognition Pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
1.2 拷贝代码

安装完成后,您就可以在本地运行以下提供的代码了。

import face_recognition
from PIL import Image, ImageDraw
from matplotlib import pyplot as plt
import time

def faceRecognition(image_path):
    # 尝试加载图片
    try:
        print(f"Loading image from {image_path}")
        image = face_recognition.load_image_file(image_path)
    except FileNotFoundError:
        return "Error: 文件未找到,请确保文件路径正确!"
    except Exception as e:
        return f"Error: {e}"

    # 人脸定位
    print("Detecting faces...")
    face_locations = face_recognition.face_locations(image)
    face_landmarks = face_recognition.face_landmarks(image)

    # 如果没有找到人脸,则返回
    if len(face_locations) == 0:
        return "没有在图片中找到人脸."

    # 打开图片并准备画图
    pil_image = Image.open(image_path)
    draw = ImageDraw.Draw(pil_image)

    for face_location, face_landmark in zip(face_locations, face_landmarks):
        top, right, bottom, left = face_location
        print(f"Drawing rectangle at location Top: {top}, Left: {left}, Bottom: {bottom}, Right: {right}")
        # 画人脸边框
        draw.rectangle(((left, top), (right, bottom)), outline=(255, 0, 0), width=3)
        # 画出人脸特征点
        for facial_feature in face_landmark.keys():
            for point in face_landmark[facial_feature]:
                draw.circle(point, radius=2, fill=(0, 255, 0))  # 使用绿色填充圆圈

    # 使用matplotlib显示图片
    plt.imshow(pil_image)
    plt.axis('off')  # 不显示坐标轴
    plt.show()

    # 保存图片
    output_path = "E:/imgs/recognized_faces_with_landmarks.jpg"
    pil_image.save(output_path)
    print(f"Image with landmarks saved to {output_path}")

if __name__ == '__main__':
    start = time.time()
    # 使用示例图片的路径
    sample_image_path = "E:/imgs/sample_image.jpg"
    output_path = faceRecognition(sample_image_path)
    print(output_path)
    end = time.time()
    print('共耗时' + str(end - start) + '秒')

2. 程序概述

这个程序使用 face_recognitionPillow 库来检测图片中的人脸,并在检测到的人脸周围画边框,同时在人脸的特征点上画绿色的小圆圈。最后,程序将修改后的图片保存到指定的路径。

3. 功能分解

  1. 导入必要的库
    • face_recognition:用于人脸检测和人脸特征点识别。
    • PIL(Pillow)库中的 ImageImageDraw:用于加载图片和在图片上画图。
  2. 定义 faceRecognition 函数
    • 参数image_path,即输入图片的路径。
    • 功能
      • 加载图片
        • 使用 face_recognition.load_image_file 尝试加载图片。
        • 如果图片不存在或发生其他错误,则捕获异常并返回错误信息。
      • 人脸定位
        • 使用 face_recognition.face_locations 方法找到图片中所有人脸的位置。
        • 使用 face_recognition.face_landmarks 方法找到每个人脸的特征点。
      • 检查是否找到人脸
        • 如果没有找到人脸,则返回相应的信息。
      • 打开图片并准备画图
        • 使用 Pillow 库打开图片。
        • 创建一个 ImageDraw 对象用于在图片上画图。
      • 画人脸边框和特征点
        • 遍历每个人脸位置和特征点。
        • 使用 draw.rectangle 方法在每个人脸周围画一个红色边框。
        • 使用 draw.circle 方法在每个人脸的特征点上画一个绿色的小圆圈。
      • 保存图片
        • 将修改后的图片保存到指定的路径(E:/imgs/recognized_faces_with_landmarks.jpg)。
      • 返回值
        • 返回保存后的图片的路径。
  3. 调用 faceRecognition 函数
    • 使用示例图片的路径(sample_image_path)作为参数调用 faceRecognition 函数。
  4. 输出 output_path
    • 打印出保存后的图片的路径,以便知道图片被保存在哪里。

4. 运行效果

4.1 单人检测效果

在这里插入图片描述

4.2 多人检测效果

在这里插入图片描述

5. 小结

以上程序接受一个图片路径作为输入,检测图片中的人脸和特征点,然后在每个人脸周围画红色边框,在特征点上画绿色小圆圈,最后将修改后的图片保存并返回保存路径。这是一个典型的人脸识别和图像处理任务,可以用于各种需要人脸识别的应用场景。

6. 进阶:人脸识别比对

在以上的基础上,我们应用欧氏距离进行人脸距离计算

6.1 定义

欧氏距离(Euclidean distance)是数学中的一个概念,用于计算两个点在欧几里得空间中的直线距离。在人脸识别和图像处理中,欧氏距离可以用来度量两个面部特征向量之间的差异,从而判断两张人脸的相似度。

6.2 原理:

在二维空间中,两个点AB之间的欧氏距离可以通过以下公式计算:

  • 第一个点A的坐标:
    A = ( x 1 , y 1 ) A = (x_1, y_1) A=(x1​,y1​)

  • 第二个点B的坐标:
    B = ( x 2 , y 2 ) B = (x_2, y_2) B=(x2​,y2​)

  • 二维空间的欧氏距离公式:
    d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} d=(x2​−x1​)2+(y2​−y1​)2

在人脸识别中,每张人脸可以表示为一个高维向量,其中每个维度对应于面部特征的一个量化值,比如眼睛的位置、鼻子的宽度、嘴巴的形状等。假设我们有两个面部特征向量AB,它们分别是n维的:

  • 向量A的表示:
    A = [ a 1 , a 2 , . . . , a n ] \textbf{A} = [a_1, a_2, ..., a_n] A=[a1​,a2​,...,an​]
  • 向量B的表示:
    B = [ b 1 , b 2 , . . . , b n ] \textbf{B} = [b_1, b_2, ..., b_n] B=[b1​,b2​,...,bn​]
6.3 公式扩展

欧氏距离的计算公式扩展到 n 维空间为:

  • n维空间的欧氏距离公式:
    d ( A , B ) = ∑ i = 1 n ( b i − a i ) 2 d(\textbf{A}, \textbf{B}) = \sqrt{\sum_{i=1}^{n} (b_i - a_i)^2} d(A,B)=i=1∑n​(bi​−ai​)2
6.4 判断人脸距离:
  1. 特征提取:首先,从每张人脸图片中提取特征,这些特征可以是面部关键点的坐标、局部特征描述符(如LBP、HOG)或者深度学习模型提取的特征向量。
  2. 特征标准化:为了消除不同量纲和数值范围的影响,通常需要对特征向量进行标准化处理。
  3. 计算距离:使用上述公式计算两个特征向量之间的欧氏距离。
  4. 相似度判断:设定一个阈值 ( \theta ),如果两个特征向量之间的欧氏距离小于这个阈值,可以认为这两张人脸是相似的或者是同一个人;如果距离大于这个阈值,则认为它们属于不同的人。
6.5 结论

欧氏距离越小,表明两张人脸越相似;欧氏距离越大,表明两张人脸的差异越大。在实际应用中,这个方法可能会受到光照、姿态、表情等因素的影响,因此通常会结合其他方法和算法来提高人脸识别的准确率和鲁棒性。

但在本次的程序中,我们为了条件方便,用了如下方式,所以得出的相似度分数越大则表示两张面孔越相似

similarity_score = 1 - face_distances[0]
6.6 程序代码
import face_recognition
from PIL import Image, ImageDraw
from matplotlib import pyplot as plt
import time


def faceRecognition(image_path, known_image_path, tolerance=0.8):
    # 尝试加载图片
    try:
        print(f"Loading image from {image_path}")
        image = face_recognition.load_image_file(image_path)
        known_image = face_recognition.load_image_file(known_image_path)
    except FileNotFoundError as e:
        return f"Error: {e}"
    except Exception as e:
        return f"Error: {e}"

    # 获取已知人脸编码
    print("Encoding known face...")
    known_face_encoding = face_recognition.face_encodings(known_image)[0]

    # 人脸定位和编码
    print("Detecting faces...")
    face_locations = face_recognition.face_locations(image)
    face_encodings = face_recognition.face_encodings(image, face_locations)

    # 如果没有找到人脸,则返回
    if len(face_locations) == 0:
        return "没有在图片中找到人脸."

    # 打开图片并准备画图
    pil_image = Image.open(image_path)
    draw = ImageDraw.Draw(pil_image)

    # 遍历每个人脸位置和人脸编码
    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        # 比较人脸
        matches = face_recognition.compare_faces([known_face_encoding], face_encoding, tolerance=tolerance)

        # 计算相似度分数
        face_distances = face_recognition.face_distance([known_face_encoding], face_encoding)
        similarity_score = 1 - face_distances[0] if face_distances[0] <= 1 else 0
        similarity_score_rounded = round(similarity_score, 2)

        name = "Unknown"
        if True in matches and similarity_score>tolerance:
            name = "Known"

        # 画人脸边框
        draw.rectangle(((left, top), (right, bottom)), outline=(255, 0, 0), width=3)
        # 打印匹配信息
        match_text = f"{name} (Match: {'Yes' if True in matches and similarity_score>tolerance else 'No'})"
        similarity_text = f"Similarity: {similarity_score_rounded}"
        draw.text((right + 10, top), f"{match_text}\n{similarity_text}", fill=(255, 255, 255))

    # 使用matplotlib显示图片
    plt.imshow(pil_image)
    plt.axis('off')  # 不显示坐标轴
    plt.show()

    # 保存图片
    output_path = "recognized_faces.png"
    pil_image.save(output_path)
    print(f"Image with recognized faces saved to {output_path}")


def CompareFace(knownpath, unknowpath):
    sample_image_path = unknowpath  # 待识别的人脸图片路径
    known_image_path = knownpath  # 已知人脸图片路径
    output_path = faceRecognition(sample_image_path, known_image_path)
    end = time.time()
    totalTime = end - start


if __name__ == '__main__':
    start = time.time()
    CompareFace("E:/imgs/img2.png", "E:/imgs/img2.png")	# 测试相同人脸图片
    CompareFace("E:/imgs/img2.png", "E:/imgs/img.png")	# 测试不同人脸图片
    end = time.time()
    totalTime = end - start
    print('共耗时 %.2f 秒'%(totalTime))

以上程序使用 face_recognition 库来来检测、编码人脸和识别图片中的人脸,并使用 matplotlib 库来显示识别结果。并可以保存带有识别结果的图片。通过调整 tolerance 参数,可以设置匹配的相似度阈值。

在以上程序中我们使用 face_distance 函数来计算检测到的人脸与已知人脸之间的距离。然后,我们将距离转换为相似度分数,并四舍五入到两位小数。匹配信息(“Match: Yes” 或 “Match: No”)和相似度分数都打印在检测到的人脸红框的右侧。

相似度分数是通过 1 - face_distances[0] 计算的,以确保分数在 0 到 1 之间。如果距离大于 1,我们将其设置为 0,因为这种情况表明两张脸完全不相似。

7. 识别效果

7.1 相同图片测试

我们传入两张相同的图片,测试结果如下:

结果正如预期一样,识别出已知且相似度为1.0,说明完全相似

在这里插入图片描述

7.2 不同图片测试

此时我们传入的是两张完全不同的图片,测试结果如下:

结果也正如预期一样,识别出未知且相似度分数只有0.17。

在这里插入图片描述

以上就是本文的全部内容了,感兴趣的小伙伴可以尝试自行扩展程序,实现一个简单的人脸识别系统。

标签:示例,Python,image,face,人脸,path,recognition,图片
From: https://blog.csdn.net/Young_Pro/article/details/140681181

相关文章

  • 太强了,Python+Excel真的是神仙组合!
    本书是由流行开源Python库xlwings的创始人:费利克斯·朱姆斯坦(FelixZumstein)所撰写。他详细阐述了如何将Python与Excel结合使用,让任务自动化,从而实现效率飞跃。为了帮助初学者克服对Python的恐惧,作者特意将教程内容设计成从简单到复杂的顺序进行介绍。这本书PDF共282页,分为4个......
  • 在 Python 中获取精确的 Android GPS 位置
    我尝试在Python中获取Android手机的GPS位置(使用QPython3应用程序)。这种可行,但是Android中似乎有几个LocationProvider:gps:纯gps定位,速度慢,耗能,但非常准确,正是我所需要的。网络:GPS和wifi/小区定位的混合,更快,但不太准确被动......
  • 使用 docker run 将 Python 单击选项传递给 ENTRYPOINT 会出现错误:“在 $PATH 中找不
    我有一个简单的python脚本,我想在docker容器内运行它。它打印一行消息“Hello{name}”。python脚本使用clickCLI界面来定义收件人名称,如果我直接运行它(不使用dockerrun命令),它将如下所示:pythonhello.py-nSmithDockerbuild命令:dockerbuild.-thello:1.......
  • 标题:在 OpenSees Python 中定义具有特定卸载行为的双线性弹塑性材料
    我正在使用Python中的OpenSees,我想定义一种在负载下表现出双线性弹塑性行为的材料。但是,我需要在卸载过程中将材质返回到其原始位置,遵循准确的加载路径。在此处输入图像描述我不确定如何在OpenSees中正确实现卸载行为,我正在寻找实现这一具体材料反应的指导。......
  • 使用正则表达式删除Python中常见的公司名称后缀
    我正在努力删除一些公司名称中的后缀。预期结果如下:原始名称:AppleInc.SonyCorporationFiatChryslerAutomobilesS.p.A.SamsungElectronicsCo.,Ltd.清除名称:AppleSonyFiatChryslerAutomobilesSamsungElectronics到目前为止我所做的:importred......
  • 如何将 Brave 网络浏览器与 python、selenium 和 chromedriver 结合使用?
    我从Google的Chrome切换到Brave网络浏览器并且很难让它像Chrome一样与Brave一起使用。Brave是基于Chromium的,所以我猜它应该不会那么难。我确保我的Brave和Chromedriver处于相同版本,像这样,~/some/path$chromedriver--versionChromeDriver76.0.3......
  • 覆盖 python 应用程序时权限被拒绝
    我使用python制作了一个粗略的自动更新应用程序,并使用freeze-cx制作了exe文件。首先,该应用程序检查firebase服务器上是否有最新版本的文件可用,如果可用则下载zip文件。并且应用程序解压并覆盖文件。this_file_path=sys.executableifgetattr(sys,'frozen......
  • Python数据分析案例55——基于LSTM结构自编码器的多变量时间序列异常值监测
    案例背景时间序列的异常值检测是方兴未艾的话题。比如很多单变量的,一条风速,一条用电量这种做时间序列异常值检测,想查看一下哪个时间点的用电量异常。多变量时间序列由不同变量随时间变化的序列组成,这些时间序列在实际应用中通常来自不同的传感器或数据源。多变量时间序列异......
  • 我没有 python 但我有 python3
    我最近格式化了我的笔记本电脑并安装了Ubuntu操作系统。我没有明确安装Python。为了检查它是否已预安装,我在终端中运行python--version并得到了这个:$python--versionCommand'python'notfound,butcanbeinstalledwith:sudoaptinstallpython3......
  • 基于YOLOv9的停车场空闲车位检测【python源码+UI界面+数据集+模型+语音报警+安装说明
    往期精品导航基于YOLOv9的脑肿瘤区域检测智慧课堂基于YOLOv8的学生上课行为检测基于YOLOv9+pyside的安检仪x光危险物物品检测(有ui)基于YOLOv9的PCB板缺陷检测基于YOLOv9的线路绝缘子缺陷检测【python源码+UI界面+数据集+模型+语音报警+安装说明】基于YOLOv9的道路状况检测【......