25.人脸关键点检测

目录

1  项目介绍

2  代码实现

2.1  导入库

2.2  定义参数

2.3  定义点位

2.4  定义 shape_to_np()

2.5  定义 visualize_facial_landmarks()

2.6  创建人脸检测器

2.7  创建人脸68点预测器

2.8  图像预处理

2.9  人脸检测

2.10  找到关键点

2.11  遍历每一部分

2.11.1  写字

2.11.2  画圆

2.11.3  提取ROI

2.11.4  展示ROI与画好点的图

2.12  展示所有区域


1  项目介绍

这个是人脸部的68个关键点

25.人脸关键点检测

我们可以看到

  • 0-16点是下巴
  • 16-21点是右眼眉(这里是镜像图像,是图中人的右眼眉)
  • 22-26点是左眼眉
  • 27-35点是鼻子
  • 36-41点是右眼
  • 42-47点是左眼
  • 48-67点是嘴

我们现在有这样一张人脸

25.人脸关键点检测

我们提取出人脸的每个部分,之后画出图像的所有器官部分

25.人脸关键点检测

25.人脸关键点检测

  • 右眼眉,由于图像是镜像的图,现在标注的眼是这个人的右眼

25.人脸关键点检测

25.人脸关键点检测

  • 左眼眉

25.人脸关键点检测

25.人脸关键点检测

  • 右眼

25.人脸关键点检测

25.人脸关键点检测

  • 左眼

25.人脸关键点检测

25.人脸关键点检测

  • 鼻子

25.人脸关键点检测

25.人脸关键点检测

  • 下巴

25.人脸关键点检测

25.人脸关键点检测

  • 整体区域

25.人脸关键点检测

我们的思路是先检测出图像中人脸的位置,然后使用68关键点对每个器官进行定位

如果找的图片的脸上胡子比较重,它识别嘴部的精度会很差

我们也可以检测一张图中的多个人脸

25.人脸关键点检测

25.人脸关键点检测

  • 需要是正面脸,不然要改代码

2  代码实现

2.1  导入库

25.人脸关键点检测

我们这里用到了collections中的OrderedDict,这个功能是创建有序字典,collections是python自带的库,dlib中有检测人脸68点的功能,我们直接使用写好的函数

2.2  定义参数

25.人脸关键点检测

shape_predictor是我们dlib做68人脸关键点检测的一个文件(相当于是一个模型),image是我们要预测的图像

2.3  定义点位

定义68点的位置,上面有介绍过对应68点的位置,这里使用到了OrderedDict,它是一个单独的类,我们在这里举个例子

25.人脸关键点检测

a = {'a':1,'c':2,'b':3}
print(type(a))
from collections import OrderedDict
b = OrderedDict([('a',1),('c',2),('b',3)])
print(type(b))
#调用的方式与和普通字典调用方式相同
print(a['a'])
print(b['a'])

25.人脸关键点检测

除了人脸68点位还有人脸五点位,这个只能检测眼镜和鼻子,它的点位是这样定义的

  • 0-1是右眼
  • 2-3是左眼
  • 4 是鼻子

25.人脸关键点检测

  • 上面这个在代码中没用到

2.4  定义 shape_to_np()

25.人脸关键点检测

传入的参数shape是一个检测好的人脸关键点对象,我们在这个函数中进行处理,进入函数后我们下面会用到shape.num_parts这个方法,我们提前打印出来看一下

25.人脸关键点检测

25.人脸关键点检测

这个值是68,之后我们使用np.zeros创建全0的numpy.ndarry,大小为(68,2),我们打印出来看一下

25.人脸关键点检测

25.人脸关键点检测

25.人脸关键点检测

一共68行,我就截取了头和尾

之后我们遍历68次,然后使用shape.part()取出每个点的坐标,然后赋值给coords对应的位置

25.人脸关键点检测

现在我们看一下更新后的coords

25.人脸关键点检测

25.人脸关键点检测

没截全部,一头一尾

2.5  定义 visualize_facial_landmarks()

这个函数是画多边形用的,我们先看传入的参数

  • image 要画的图像
  • shape 多边形的点
  • colors 颜色,默认为None,在函数中会定义
  • alpha 这个是叠加比例,可以理解为多边形的透明度

25.人脸关键点检测

进入函数后,首先复制两张图像

25.人脸关键点检测

之后设置颜色,一共七个区域,我们设置为不同的颜色,如果我们之前设置了颜色就按设置的来,设置也必须设置7个

25.人脸关键点检测

之后遍历七个区域,然后提取字典中的起始点和终止点两个索引值

25.人脸关键点检测

之后把这些值交给pts

25.人脸关键点检测

我们七个区域中,唯一不是闭合图形的就是下巴jaw,如果判定是下巴区域,我们就用点给它连起来

当然我们想给它画成多边形也能画,这样它的区域就是整张脸

25.人脸关键点检测

这里是画在overlay上,一会儿我们要对overlay与output进行图像叠加

其余都是闭合图形,我们首先使用convexHull()计算凸包,参数为多边形点集合,它大致是这个意思

25.人脸关键点检测

我们原图像是一个手

25.人脸关键点检测

计算凸包之后画出来

25.人脸关键点检测

如果想详细了解的话可以看一下这个 OpenCV入门之寻找图像的凸包(convex hull) - 山阴少年 - 博客园

凸包计算完成后我们将他画在overlay上

25.人脸关键点检测

全部画完之后我们将overlay与output进行图像融合,比例为overlay 0.75,alpha 0.25,将融合后的图像赋值给output,最后返回融合后的图像

25.人脸关键点检测

2.6  创建人脸检测器

dlib中有多种人脸检测的工具,我们使用的是get_frontal_face_detector(),这个是专门检测人的正脸的

25.人脸关键点检测

2.7  创建人脸68点预测器

25.人脸关键点检测

2.8  图像预处理

25.人脸关键点检测

现在我们得到了宽为500,宽高比相同的灰度图像

2.9  人脸检测

25.人脸关键点检测

这里有两个参数

  • gray 要检测的图像
  • 1 放大倍数,如果输入0是不放大,输入1是放大一倍,输入2是放大两倍,放的越大可以越好的检测图像中的所有人脸,相应运行的速度也会越慢

我们可以看一下rects

25.人脸关键点检测

25.人脸关键点检测

他会返回rectangles这个对象,通过名称我们可以得知,这个对象中都是矩形,那么我们尝试遍历一下其中的内容

25.人脸关键点检测

发现只有里面只有一个值,这个值是一个矩形的坐标,这个是我们图像中人脸的坐标

25.人脸关键点检测

2.10  找到关键点

现在我们对着原始图像的rect部分检测68个关键点

25.人脸关键点检测

我们看一下这个shape

25.人脸关键点检测

发现返回了一个这个对象

25.人脸关键点检测

之后我们把这个对象传给上面定义的shape_to_np()

25.人脸关键点检测

这个函数让我们拿到了大小为(68,2)的numpy.ndarray,其中内容为68个关键点的坐标

2.11  遍历每一部分

25.人脸关键点检测

FACIAL_LANDMARKS_68_IDXS是我们上面定义的有序字典,一共七个部分

25.人脸关键点检测

遍历的时候赋值了三个变量,我用mouth举个例子,name='mouth',i=48,j=68

25.人脸关键点检测

2.11.1  写字

进入循环后,首先我们复制一张原图像,然后在复制图像上把name变量写在图片上

25.人脸关键点检测

2.11.2  画圆

我们获取从i到j的点坐标,然后以它们为圆心,画半径为3的圆,之后使用红色进行填充

25.人脸关键点检测

2.11.3  提取ROI

之后将从i-j的点拟合成轮廓,赋值给(x,y,w,h),之后我们截取这个矩形的地方,然后把它的宽变为250,宽高比与轮廓矩形相同的图像

25.人脸关键点检测

2.11.4  展示ROI与画好点的图

25.人脸关键点检测

2.12  展示所有区域

遍历结束后,我们将原图像与shape(大小为68*2的关键点坐标)传给visualize_facial_landmarks()进行多边形绘制,之后展示出来

25.人脸关键点检测

上一篇:Leetcode - 68. 文本左右对齐


下一篇:LeetCode-68-文本左右对齐