ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

25.人脸关键点检测

2021-09-14 19:04:36  阅读:287  来源: 互联网

标签:25 shape 人脸 图像 68 我们 2.11 关键点


目录

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个关键点

我们可以看到

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

我们现在有这样一张人脸

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

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

  • 左眼眉

  • 右眼

  • 左眼

  • 鼻子

  • 下巴

  • 整体区域

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

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

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

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

2  代码实现

2.1  导入库

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

2.2  定义参数

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

2.3  定义点位

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

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'])

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

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

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

2.4  定义 shape_to_np()

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

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

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

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

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

没截全部,一头一尾

2.5  定义 visualize_facial_landmarks()

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

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

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

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

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

之后把这些值交给pts

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

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

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

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

我们原图像是一个手

计算凸包之后画出来

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

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

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

2.6  创建人脸检测器

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

2.7  创建人脸68点预测器

2.8  图像预处理

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

2.9  人脸检测

这里有两个参数

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

我们可以看一下rects

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

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

2.10  找到关键点

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

我们看一下这个shape

发现返回了一个这个对象

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

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

2.11  遍历每一部分

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

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

2.11.1  写字

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

2.11.2  画圆

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

2.11.3  提取ROI

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

2.11.4  展示ROI与画好点的图

2.12  展示所有区域

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

标签:25,shape,人脸,图像,68,我们,2.11,关键点
来源: https://blog.csdn.net/potato123232/article/details/120293983

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有