使用 dlib、OpenCV 和 Python 检测面部标记

今天,我们将使用dlib和OpenCV来检测图像中的面部标记。dlib的安装教程:

https://wanghao.blog.csdn.net/article/details/121470556

人脸检测器模型:

https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/50939290

人脸标记已成功应用于人脸对齐、头部姿势估计、人脸交换、眨眼检测等领域。

在今天的博客文章中,我们将重点介绍面部标记的基础知识,包括:

1、确切的面部标记是什么以及它们是如何工作的。

2、如何使用dlib、OpenCV和Python从图像中检测和提取面部标记。

这篇博文的主要分三个部分:

1、将讨论面部标记以及它们为什么被用于计算机视觉应用。

2、演示如何使用dlib、OpenCV和Python检测和提取面部标记。

3、我们将看一些将面部标记检测应用于图像的结果。

什么是面部标记?

人脸标记点检测是形状预测问题的一个子集。给定一个输入图像(通常是一个指定感兴趣对象的ROI),形状预测器尝试沿形状定位感兴趣的关键点。

在人脸标记的背景下,我们的目标是使用形状预测方法检测人脸上的重要人脸结构。

因此,检测面部标记是一个两步过程:

​ 步骤1:在图像中定位人脸。

​ 步骤2:检测人脸ROI上的关键面部结构。

人脸检测(步骤1)可以通过多种方式实现。

我们可以使用OpenCV内置的Haar级联。

我们可以将预先训练好的HOG+线性SVM对象检测器专门用于人脸检测任务。

或者我们甚至可以使用基于深度学习的算法进行人脸定位。

无论哪种情况,用于检测图像中人脸的实际算法都无关紧要。相反,重要的是,通过某种方法,我们获得了面边界框(即,图像中面的(x,y)-坐标)。

给定面部区域,我们可以应用步骤2:检测面部区域中的关键面部结构。

有多种面部标记检测器,但所有方法基本上都试图定位和标记以下面部区域:

  • 右眉

  • 左眉

  • 右眼

  • 左眼

dlib库中包含的面部标记检测器是Kazemi和Sullivan(2014)提出的一系列回归树的一毫秒面部校准的实现。

此方法首先使用:

  • 图像上标记的面部标记的训练集。这些图像被手动标记,指定每个面部结构周围区域的特定(x,y)坐标。

  • 先验,更具体地说,是输入像素对之间距离的概率。

给定该训练数据,训练回归树集合,以直接从像素强度本身估计面部标记位置(即,不进行“特征提取”)。

最终的结果是一个面部标记检测器,可用于实时检测具有高质量预测的面部标记。

dlib的面部标记检测器

dlib库中预先训练的面部标记检测器用于估计映射到面部结构的68(x,y)坐标的位置。

68个坐标的索引可在下图中显示:

这些注释是68点iBUG 300-W数据集的一部分,dlib面部标记预测器是在该数据集上训练的。

值得注意的是,还有其他风格的面部标记检测器,包括可以在HELEN数据集上训练的194点模型。

无论使用哪一个数据集,都可以利用相同的dlib框架在输入训练数据上训练形状预测器-如果您想训练面部标记检测器或自定义形状预测器,这非常有用。

在这篇博文的剩余部分,我将演示如何在图像中检测这些面部标记。

使用dlib、OpenCV和Python检测面部标记

这篇博文使用到了imutils库face_utils.py中的两个函数。

第一个实用函数是rect_to_bb,是“矩形到边框”的缩写:

def rect_to_bb(rect):#获取dlib预测的边界并将其转换#按照我们通常使用的格式(x,y,w,h)#使用OpenCVx = rect.left()y = rect.top()w = rect.right() - xh = rect.bottom() - y# 返回一个元组 (x, y, w, h)return (x, y, w, h)

此函数接受一个参数rect,该参数假定为dlib检测器(即面部检测器)生成的边框矩形。

rect对象包括检测的(x,y)-坐标。

然而,在OpenCV中,我们通常认为边界框是“(x,y,width,height)”,因此为了方便起见,rect_to_bb函数将这个rect对象转换为4元组坐标。

第二,shape_to_np函数:

def shape_to_np(shape, dtype="int"):#初始化(x,y)-坐标列表coords = np.zeros((68, 2), dtype=dtype)#在68个面部标记上循环并转换它们#到(x,y)-坐标的2元组for i in range(0, 68):coords[i] = (shape.part(i).x, shape.part(i).y)#返回(x,y)坐标的列表return coords

dlib面部标记检测器将返回一个包含面部标记区域68(x,y)坐标的形状对象。

使用shape_to_np函数,我们可以将这个对象转换成一个NumPy数组。

有了这两个辅助函数,我们现在就可以检测图像中的面部标记了。

图像

打开一个新文件,将其命名为facial_landmarks.py,然后插入以下代码:

# import the necessary packages
from imutils import face_utils
import numpy as np
import argparse
import imutils
import dlib
import cv2
#构造参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,help="path to facial landmark predictor")
ap.add_argument("-i", "--image", required=True,help="path to input image")
args = vars(ap.parse_args())

导入所需的Python包。

将使用imutils的face_utils子模块访问上面详述的助手函数。

然后将导入dlib。

解析我们的命令行参数:

–shape-predictor:这是通往dlib预先训练的面部标记检测器的路径。你可以在这里下载检测器模型,也可以使用本文的“下载”部分来获取代码+示例图像+预先训练过的检测器。

–image:我们要检测面部标记的输入图像的路径。

既然我们的导入和命令行参数已经处理完毕,让我们初始化dlib的面部检测器和面部标记预测器:

# 初始化dlib的人脸检测器(基于HOG)然后创建
# 面部标记预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

初始化dlib的预训练人脸检测器,该检测器基于对用于对象检测的定向梯度标准直方图+线性SVM方法的修改。

然后使用提供的shape_predictor的路径加载面部标记预测器。

但是,在我们能够实际检测面部标记点之前,我们首先需要检测输入图像中的面部:

# 加载输入图像,调整大小,并将其转换为灰度
image = cv2.imread(args["image"])
image = imutils.resize(image, width=500)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 在灰度图像中检测人脸
rects = detector(gray, 1)

通过OpenCV从磁盘加载我们的输入图像,然后通过调整图像大小使其具有500像素的宽度并将其转换为灰度来预处理图像。

处理检测图像中面的边界框。

探测器的第一个参数是我们的灰度图像(尽管这种方法也可以用于彩色图像)。

第二个参数是在应用检测器之前放大图像时要应用的图像金字塔层的数量(这相当于在图像上计算cv2.N次)。

在人脸检测之前提高输入图像分辨率的好处是,它可能允许我们检测图像中的更多人脸-缺点是输入图像越大,检测过程的计算成本就越高。

给定图像中人脸的(x,y)-坐标,我们现在可以对每个人脸区域应用人脸标记检测:

# 循环面部检测
for (i, rect) in enumerate(rects):# 确定面部区域的面部标志,然后# 将面部标志 (x, y) 坐标转换为 NumPy数组shape = predictor(gray, rect)shape = face_utils.shape_to_np(shape)# 将 dlib 的矩形转换为 OpenCV 样式的边界框# [即(x, y, w, h)],然后绘制人脸边界框(x, y, w, h) = face_utils.rect_to_bb(rect)cv2.rectangle(image, (x, y), (x + w, y + h), (255, 255, 0), 2)# 显示人脸编号cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)# 循环面部标志的 (x, y) 坐标# 并将它们绘制在图像上for (x, y) in shape:cv2.circle(image, (x, y), 1, (0, 255, 0), -1)
# 显示带有人脸检测 + 人脸标记的输出图像
cv2.imshow("Output", image)
cv2.waitKey(0)

循环每个人脸检测。

对于每个人脸检测,给出68(x,y)-坐标,该坐标映射到图像中的特定人脸特征。

然后将dlib形状对象转换为具有形状(68,2)的NumPy数组。

绘制图像上检测到的人脸周围的边界框,绘制人脸的索引。

最后,在检测到的面部标记上循环并分别绘制它们。

将输出图像显示到屏幕上。

测试结果

打开终端输入:

python facial_landmarks.py --shape-predictor shape_predictor_68_face_landmarks.dat --image 11.jpg

视频或摄像头

让我们继续开始这个面部标记的例子。这次调用摄像头

打开一个新文件,将其命名为 video_facial_landmarks.py ,并插入以下代码:

# import the necessary packages
from imutils.video import VideoStream
from imutils import face_utils
import datetime
import argparse
import imutils
import time
import dlib
import cv2

导入需要的包。

然后,让我们解析命令行参数:

# 构造参数 parse 并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,help="path to facial landmark predictor")
ap.add_argument("-r", "--picamera", type=int, default=-1,help="whether or not the Raspberry Pi camera should be used")
args = vars(ap.parse_args())

脚本需要一个命令行参数,然后是第二个可选参数,每个参数的详细信息如下:

–shape-predictor :dlib 的预训练面部标志检测器的路径。
–picamera :可选的命令行参数,此开关指示是否应使用 Raspberry Pi 摄像头模块而不是默认的网络摄像头/USB 摄像头。 提供一个 > 0 的值以使用您的 Raspberry Pi 相机。

现在我们的命令行参数已经解析完毕,我们需要初始化 dlib 的基于 HOG + 线性 SVM 的人脸检测器,然后加载面部标志预测器:

# 初始化dlib的人脸检测器(基于HOG)然后创建
# 面部标志预测器
print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

下一个代码块简单地处理初始化我们的 VideoStream 并允许相机传感器预热:

# 初始化视频流并让相机传感器预热
print("[INFO] camera sensor warming up...")
vs = VideoStream(usePiCamera=args["picamera"] > 0).start()
time.sleep(2.0)

我们视频处理管道的核心可以在下面的 while 循环中找到:

# 循环视频流中的帧
while True:# 从线程视频流中抓取帧,将其调整为# 最大宽度为 400 像素,并将其转换为# 灰度frame = vs.read()frame = imutils.resize(frame, width=400)gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 在灰度帧中检测人脸rects = detector(gray, 0)# 循环面部检测for rect in rects:# 确定面部区域的面部标志,然后# 将面部标志 (x, y) 坐标转换为 NumPy数组shape = predictor(gray, rect)shape = face_utils.shape_to_np(shape)# 循环面部标志的 (x, y) 坐标# 并将它们绘制在图像上for (x, y) in shape:cv2.circle(frame, (x, y), 1, (0, 0, 255), -1)# 显示帧cv2.imshow("Frame", frame)key = cv2.waitKey(1) & 0xFF# 如果按下 `q` 键,则跳出循环if key == ord("q"):break

这里面的逻辑和图像的相同,接下来我们测试一下。

python video_facial_landmarks.py --shape-predictor shape_predictor_68_face_landmarks.dat

总结

在今天的博客文章中,我们了解了什么是面部标记,以及如何使用dlib、OpenCV和Python检测它们。

检测图像中的面部标记包括两个步骤:

首先,我们必须在图像中定位人脸。这可以使用许多不同的技术来实现,但通常涉及Haar级联或HOG+线性SVM检测器(但任何在人脸周围生成边界框的方法都足够了)。

应用形状预测器,特别是面部标记检测器,以获得面部ROI中面部区域的(x,y)-坐标。

鉴于这些面部标记,我们可以应用多种计算机视觉技术,包括:

面部部分提取(即鼻子、眼睛、嘴、下颌线等)

面部对齐

头部姿态估计

面交换

眨眼检测

……

希望这篇文章能给你带来帮助!!!

完整的代码和文件详见:

https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/50945619

人脸检测进阶:使用 dlib、OpenCV 和 Python 检测面部标记相关推荐

  1. python人脸识别考勤系统 dlib+OpenCV和Pyqt5、数据库sqlite 人脸识别系统 计算机 毕业设计 源码

    一.项目介绍 Python语言.dlib.OpenCV.Pyqt5界面设计.sqlite3数据库 本系统使用dlib作为人脸识别工具,dlib提供一个方法可将人脸图片数据映射到128维度的空间向量,如 ...

  2. 人脸检测实战进阶:使用 OpenCV 进行活体检测

    使用 OpenCV 进行活体检测 在本篇博文中,您将学习如何使用 OpenCV 执行活体检测.您将创建一个活体检测器,该检测器能够在人脸识别系统中发现假人脸并执行反人脸欺骗. 在教程的第一部分,我们将 ...

  3. python人脸识别理论_使用OpenCV和Python进行人脸识别

    介绍 人脸识别是什么?或识别是什么?当你看到一个苹果时,你的大脑会立刻告诉你这是一个苹果.在这个过程中,你的大脑告诉你这是一个苹果水果,用简单的语言来说就是识别.那么什么是人脸识别呢?我肯定你猜对了. ...

  4. 文本检测实战:使用OpenCV实现文本检测(EAST 文本检测器)

    在本教程中,您将学习如何使用 OpenCV 使用 EAST 文本检测器检测图像中的文本. EAST 文本检测器要求我们在我们的系统上运行 OpenCV 3.4.2 或 OpenCV 4 . 论文原文: ...

  5. python 圆形检测_python下用OpenCV的圆形检测

    一.简介: 初次使用python的你一定感受到了python的便捷.作为高级编程语言只需调用类库即可. 对于圆形物体识别问题,opencv提供了大量方法. (代码文末附上) 二.检测步骤: 2.1读取 ...

  6. opencv和python是什么关系_使用OpenCV和Python检测眼睛

    今天,我们将学习如何借助称为霍夫变换的技术来检测图像中的直线和圆. 什么是霍夫空间? 在开始对图像应用霍夫变换之前,我们需要了解霍夫空间是什么,我们将通过示例的方式来学习. 参数空间 当我们处理图像时 ...

  7. python 椭圆检测_使用OpenCV和Python检测触摸/重叠圆/椭圆

    这是我检测圈子的尝试.综上所述 >执行BGR-> HSV转换,并使用V通道进行处理 V通道: >阈值,应用形态关闭,然后进行距离转换(我会称之为dist) 分区形象: >创建一 ...

  8. dlib 使用OpenCV,Python和深度学习进行人脸识别 源代码

    请直接访问原文章 dlib 使用OpenCV,Python和深度学习进行人脸识别 源代码 https://hotdog29.com/?p=595 在 2019年7月7日 上张贴 由 hotdog发表回 ...

  9. python视频人脸检测_OpenCV + python 实现人脸检测(基于照片和视频进行检测)

    OpenCV + python 实现人脸检测(基于照片和视频进行检测) Haar-like 通俗的来讲,就是作为人脸特征即可. Haar特征值反映了图像的灰度变化情况.例如:脸部的一些特征能由矩形特征 ...

最新文章

  1. Pandas缺失数据
  2. html设置根rem,经过js动态设置根元素的rem方案
  3. HQL查询(分页查询,动态sql查询,参数查询)
  4. python 输出“Hello, world”
  5. 在HTML中小心使用空格和回车
  6. 洛谷 P3469 [POI2008]BLO-Blockade (Tarjan,割点)
  7. 如何将 png 图片转换为 eps ?
  8. 模线性同余方程组求解
  9. 大数据改变中国交通浙江用阿里云看未来
  10. Samba 共享目录启动mysql
  11. 图像去雾之何凯明暗通道先验去雾算法原理及c++代码实现
  12. 外螺纹对照表_常用螺纹规范对照表
  13. Linux-war包解压与压缩
  14. 骨科手术ICD编码主要缺陷与原因分析
  15. Axure原型设计工具--产品经理必备
  16. WPS 解决插入尾注后无法添加分节页符
  17. python主成分分析_Python的主成分分析PCA算法
  18. 化合物相似性搜索_分子相似性的应用
  19. 手机安装linux发行版,为亲朋好友挑选一款合适的Linux发行版
  20. Java实现微信开发者-测试账号申请及配置

热门文章

  1. mysql数据库忘记root密码
  2. 常见的机器学习数据挖掘知识点之Basis
  3. 使用nodejs Crawler模块 爬取页面dom数据,图片和视频等详解
  4. 万字长文科普:什么是低代码?
  5. 同济大学高等数学上册第四章不定积分以及每日一题
  6. CSS 选择器 :last-child与:last-of-type的区别
  7. java转移oraclr数据_Oracle转义 - JAVA_NINA的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. matlab 图像退化,基于matlab的退化图像复原(一)------图像退化处理
  9. PNG背景透明 转成 BMP背景透明
  10. DSP看门狗实验源程序