基于 dlib 的人脸检测(Python)


前言

人脸检测是一种计算机视觉技术,旨在识别并定位图像或视频中人脸的位置。68点人脸检测是一种比较精确的人脸检测方法,它可以识别人脸的各个部分,并给出每个部分的具体位置。

68点人脸检测使用的是一种基于形状模型的方法,首先会将人脸图像与一个已知的人脸模型进行匹配,然后根据模型的特征点,如眉毛、眼睛、鼻子、嘴巴等,来确定人脸的具体位置和姿态。这种方法可以高度准确地检测出人脸的各个部分,而不仅仅是简单地判断人脸是否存在。

68点人脸检测有着广泛的应用前景。首先,它可以用于人脸识别技术,通过对人脸进行特征点定位,可以更准确地识别和比对不同人脸之间的相似性。其次,它可以用于人脸表情分析,通过监测人脸特征点的位置变化,可以准确地分析人脸表情的细微变化,从而进行情绪识别等应用。此外,它还可以用于人脸美化技术,通过精确定位人脸的各个特征点,可以进行人脸变形、修饰等操作,从而提升人脸的美观度。


一、环境配置

因为是由python实现,所以我们需要安装pycharm,然后跟着下面的步骤创建环境并且安装cv2库和dlib库。
打开 Anaconda Prompt(或命令提示符,如果 Anaconda 已添加到系统路径中)。
输入以下命令创建一个名为 myenv 的新环境(你可以将 myenv 替换为你想要的环境名称):

     conda create --name myenv

当提示时,输入 y 确认安装。

2.激活环境:

创建环境后,输入以下命令激活环境:

     conda activate myenv

3.安装 OpenCV:

在激活的环境中,输入以下命令安装 OpenCV:

     conda install -c conda-forge opencv

4.安装以下两个库:

#安装Cmake库
pip install Cmake
 
#安装boost库
pip install boost

5.whl安装:

点击下载添加链接描述

6. 在下载dlib文件的文件夹下运行cmd:

   cd /path/to/your/folder
   pip install dlib

到这里我们就完成了准备工作。

二、代码解释

1.引入库

代码如下(示例):

import dlib
import cv2

dlib库:主要用于人脸检测和面部特征点提取等任务。它提供了高效的机器学习算法和工具,在计算机视觉领域中被广泛应用。
cv2(OpenCV)库:是一个强大的计算机视觉库,提供了许多用于图像和视频处理的功能,包括图像读取、显示、处理以及人脸检测等。

2.设置人脸检测器和特征提取器

代码如下(示例):

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('E:/Vision/Opencv_dlib/shape_predictor_68_face_landmarks.dat/shape_predictor_68_face_landmarks.dat')
img = cv2.imread("E:\Vision\Opencv_dlib\picture.jpg")

获取人脸检测器:
detector = dlib.get_frontal_face_detector():这行代码调用dlib库中的函数获取一个正面人脸检测器。这个检测器是预先训练好的,可以在图像中快速检测出正面的人脸区域。它的工作原理是基于特定的算法和模型,通过分析图像中的像素值和特征来确定人脸的位置。
设置特征提取器:
predictor = dlib.shape_predictor(‘…’):这里使用一个预先训练好的模型文件来构建面部特征提取器。这个模型文件通常是通过大量的人脸数据进行训练得到的,可以在检测到的人脸区域上准确地提取出 68 个面部特征点的位置。这些特征点包括眼睛、鼻子、嘴巴等部位的关键点,可以用于进一步的人脸识别、表情分析等任务。
读取图片:
img = cv2.imread(“…”):使用cv2库的imread函数读取一张指定路径下的图片。这张图片将作为后续人脸检测和特征点提取的输入。

3.定义人脸检测函数 face_detect_demo

def face_detect_demo():
    face_detect = cv2.CascadeClassifier(
        "F:/pycharm/Anaconda/envs/study/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml")
    faces = face_detect.detectMultiScale(src)
    for x, y, w, h in faces:
        cv2.rectangle(src, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.imshow("face_detect", src)

加载人脸检测分类器:
face_detect = cv2.CascadeClassifier(…):使用cv2库的CascadeClassifier类加载一个预先训练好的人脸检测分类器。这个分类器是通过大量的人脸和非人脸图像进行训练得到的,可以在图像中检测出人脸区域。这里使用的分类器文件路径是F:/pycharm/Anaconda/envs/study/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml,这是 OpenCV 中常用的人脸检测分类器文件之一。
进行人脸检测:
faces = face_detect.detectMultiScale(src):使用加载的人脸检测分类器在输入图像src上进行人脸检测。detectMultiScale方法会返回一个列表,其中每个元素都是一个包含检测到的人脸区域的坐标和大小的四元组(x, y, w, h),分别表示人脸区域左上角的横坐标、纵坐标、宽度和高度。
绘制矩形框:
for x, y, w, h in faces::遍历检测到的人脸区域列表。
cv2.rectangle(src, (x, y), (x + w, y + h), (0, 0, 255), 2):对于每个检测到的人脸区域,使用cv2库的rectangle函数在输入图像src上绘制一个红色((0, 0, 255))的矩形框。参数分别是输入图像、矩形框的左上角坐标((x, y))、右下角坐标((x + w, y + h))、颜色和线宽(这里是 2)。
显示结果:
cv2.imshow(“face_detect”, src):使用cv2库的imshow函数显示标注了人脸矩形框的图像,窗口名为 “face_detect”。

4.读取图片、调用检测函数和显示图片

src = cv2.imread("E:\Vision\Opencv_face\picture.jpg")
cv2.imshow("input image", src)
face_detect_demo()
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imshow('img2', img)

读取另一张图片:
src = cv2.imread(“…”):使用cv2库的imread函数读取另一张指定路径下的图片,存储在变量src中。
显示图片:
cv2.imshow(“input image”, src):使用cv2库的imshow函数显示刚刚读取的图片,窗口名为 “input image”。
调用人脸检测函数:
face_detect_demo():调用前面定义的人脸检测函数,对src图片进行人脸检测并在图像上绘制矩形框,然后显示结果。
等待用户按键:
cv2.waitKey(0):使用cv2库的waitKey函数等待用户按下任意键。参数为 0 表示无限等待,直到有按键按下。
关闭所有窗口:
cv2.destroyAllWindows():使用cv2库的destroyAllWindows函数关闭所有打开的窗口,释放资源。
再次显示图片:
cv2.imshow(‘img2’, img):再次显示之前读取的img图片,窗口名为 “img2”。这里可能是为了在后续的处理中展示不同的图片或者用于对比。

5.人脸检测和特征点提取

dets = detector(img, 1)
for k, d in enumerate(dets):
    print("dets{}".format(d))
    print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
        k, d.left(), d.top(), d.right(), d.bottom()))
    shape = predictor(img, d)
    print("Part 0: {}, Part 1: {}...".format(shape.part(0), shape.part(1)))
    for index, pt in enumerate(shape.parts()):
        print('Part {}: {}'.format(index, pt))
        pt_pos = (pt.x, pt.y)
        cv2.circle(img, pt_pos, 1, (255, 0, 0), 2)
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, str(index + 1), pt_pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)
cv2.imshow('img', img)
k = cv2.waitKey()
cv2.destroyAllWindows()

进行人脸检测:
dets = detector(img, 1):使用dlib的人脸检测器在img图片上进行人脸检测。参数 1 可能是一个标志或者参数,具体含义取决于dlib的实现。检测结果存储在dets列表中,每个元素代表一个检测到的人脸区域。
遍历检测到的人脸区域:
for k, d in enumerate(dets)::使用enumerate函数遍历检测到的人脸区域列表,同时获取每个区域的下标k和区域对象d。
print(“dets{}”.format(d)):打印出检测到的人脸区域对象,可能是为了调试或者查看检测结果的详细信息。
print(“Detection {}: Left: {} Top: {} Right: {} Bottom: {}”.format(k, d.left(), d.top(), d.right(), d.bottom())):打印出每个检测到的人脸区域的位置信息,包括左、上、右、下边界的坐标。
提取面部特征点:
shape = predictor(img, d):使用特征提取器在检测到的人脸区域d上提取 68 个面部特征点的位置,结果存储在shape对象中。
打印部分特征点信息:
print(“Part 0: {}, Part 1: {}…”.format(shape.part(0), shape.part(1))):打印出第一个和第二个特征点的坐标,可能是为了调试或者查看特征点提取的初步结果。
遍历每个特征点:
for index, pt in enumerate(shape.parts())::使用enumerate函数遍历提取到的面部特征点列表,同时获取每个特征点的下标index和特征点对象pt。
print(‘Part {}: {}’.format(index, pt)):打印出每个特征点的序号和坐标,可能是为了调试或者查看特征点的详细信息。
pt_pos = (pt.x, pt.y):将特征点的坐标存储在pt_pos变量中,方便后续的处理。
cv2.circle(img, pt_pos, 1, (255, 0, 0), 2):使用cv2库的circle函数在img图片上绘制一个红色((255, 0, 0))的小圆点,表示特征点的位置。参数分别是输入图像、特征点坐标、圆的半径(这里是 1)、颜色和线宽(这里是 2)。
font = cv2.FONT_HERSHEY_SIMPLEX:设置用于标注特征点序号的字体为cv2库中的FONT_HERSHEY_SIMPLEX字体。
cv2.putText(img, str(index + 1), pt_pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA):使用cv2库的putText函数在特征点旁边标注特征点的序号。参数分别是输入图像、要标注的文本(这里是特征点序号加 1,因为序号从 0 开始)、文本的位置(特征点坐标)、字体、字体大小、颜色、线宽和文本对齐方式。
显示结果:
cv2.imshow(‘img’, img):使用cv2库的imshow函数显示标注了面部特征点的图片,窗口名为 “img”。
等待用户按键并关闭窗口:
k = cv2.waitKey():使用cv2库的waitKey函数等待用户按下任意键,返回按键的 ASCII 值存储在k变量中。
cv2.destroyAllWindows():使用cv2库的destroyAllWindows函数关闭所有打开的窗口,释放资源。
总的来说,这段代码首先读取两张图片,对其中一张使用 OpenCV 的人脸检测分类器进行人脸检测并显示结果,然后对另一张图片使用dlib进行人脸检测和面部特征点提取,并在图像上标注特征点后显示。这种方法可以用于人脸识别、表情分析、人脸对齐等计算机视觉任务中。同时,通过打印出检测到的人脸区域和特征点的信息,可以方便地进行调试和分析。
完整代码

import dlib
import cv2

# 与人脸检测相同,使用dlib自带的frontal_face_detector作为人脸检测器
detector = dlib.get_frontal_face_detector()

# 使用官方提供的模型构建特征提取器
predictor = dlib.shape_predictor('E:/Vision/Opencv_dlib/shape_predictor_68_face_landmarks.dat/shape_predictor_68_face_landmarks.dat')
# cv2读取图片
img = cv2.imread("E:\Vision\Opencv_dlib\picture.jpg")


def face_detect_demo():
    # gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
    face_detect = cv2.CascadeClassifier(
        "F:/pycharm/Anaconda/envs/study/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml")
    faces = face_detect.detectMultiScale(src)
    for x, y, w, h in faces:
        cv2.rectangle(src, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.imshow("face_detect", src)


src = cv2.imread("E:\Vision\Opencv_face\picture.jpg")  # 读取图片位置
cv2.imshow("input image", src)
face_detect_demo()

cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imshow('img2', img)

# 与人脸检测程序相同,使用detector进行人脸检测 dets为返回的结果
dets = detector(img, 1)

# 使用enumerate 函数遍历序列中的元素以及它们的下标
# 下标k即为人脸序号
# left:人脸左边距离图片左边界的距离 ;right:人脸右边距离图片左边界的距离
# top:人脸上边距离图片上边界的距离 ;bottom:人脸下边距离图片上边界的距离
for k, d in enumerate(dets):
    print("dets{}".format(d))
    print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
        k, d.left(), d.top(), d.right(), d.bottom()))

    # 使用predictor进行人脸关键点识别 shape为返回的结果
    shape = predictor(img, d)
    # 获取第一个和第二个点的坐标(相对于图片而不是框出来的人脸)
    print("Part 0: {}, Part 1: {} ...".format(shape.part(0), shape.part(1)))

    # 绘制特征点
    for index, pt in enumerate(shape.parts()):
        print('Part {}: {}'.format(index, pt))
        pt_pos = (pt.x, pt.y)
        cv2.circle(img, pt_pos, 1, (255, 0, 0), 2)
        # 利用cv2.putText输出1-68
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, str(index + 1), pt_pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)

cv2.imshow('img', img)
k = cv2.waitKey()
cv2.destroyAllWindows()

三、结果示例

在这里插入图片描述
**加粗样式
**

总结

大家有任何问题都可以在评论区和私信跟我联系,互相交流学习,本人也是研一刚开始学视觉的菜鸟一枚。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值