赞
踩
目录
人脸轮廓是进行人脸识别的重要特征之一。通过对人脸轮廓的提取和比对,可以实现身份验证、人脸识别等应用,在安全监控、公共交通、社交网络等领域具有广泛的应用价值。而且,人脸轮廓绘制可以用于人机交互中的人脸动画、虚拟现实、游戏娱乐等领域。通过对人脸轮廓的捕捉和模拟,可以实现对人物角色的面部表情的逼真呈现,提高人机交互的体验和效果。人脸轮廓绘制作为一种重要的计算机视觉和图像处理技术,具有广泛的应用前景和价值。
在opencv中,常使用下列函数寻找人脸关键点:
cv2.convexHull(points, hull=None, clockwise=None, returnPoints=None)
该函数主要用于计算一个点集的凸包,其中各参数详解如下:
points
:一个二维的numpy数组,其中包含了输入的点。每个点应当以一个元组的形式表示,例如(x, y)
。hull
:一个可选的参数,用于指定输出凸包的数组。如果这个参数没有指定,函数会创建一个新的数组来存储结果。clockwise
:一个可选的布尔值,用于确定点集的顺序。如果这个参数没有指定,函数会根据输入点集的形状自动决定。returnPoints
:一个可选的布尔值,用于确定是否返回凸包中的点。如果这个参数没有指定,函数会返回一个包含凸包点的数组。该函数通过接收一组人脸关键点,并返回表示这些点凸包的二维 numpy 数组。这个凸包就是包含所有人脸关键点的最小凸多边形。这个多边形可以用来表示人脸的外部轮廓,后续通过绘制函数对上述所标示的凸包进行绘制,即人脸关键点轮廓。
这里,将通过上述函数并结合绘制函数,进行实际的人脸关键点轮廓绘制示范
- def drawLine(start,end): #将指定的点连接起来
- pts = np.array(shape[start:end]) # 获取点集,并将矩阵matrix数据转换为array数据
- for l in range(1, len(pts)):
- ptA = tuple(pts[l - 1])
- ptB = tuple(pts[l])
- cv2.line(image, ptA, ptB, (0, 255, 0), 2)
定义用于在图像上绘制线段的函数,在找出人脸的关键点后,通过该函数将各点使用线段进行连接,即构成了人脸的关键点轮廓,其中部分参数含义如下:
pts = np.array(shape[start:end]):
将 shape
数组的子序列从 start
到 end
索引转换为 Numpy 数组。这样做是为了便于后续的数组操作。ptA = tuple(pts[l - 1]):
在循环内,这一行获取前一个点的坐标,并将其转换为元组,以供cv2.line()
函数使用。cv2.line(image, ptA, ptB, (0, 255, 0), 2):
使用 cv2.line()
函数在图像上绘制线段。该函数的参数包括:
image:
要在其上绘制线段的图像。ptA
和 ptB:
线段的两个端点的坐标(元组形式)。(0, 255, 0)
:线段的颜色,这里表示为 BGR(蓝色,绿色,红色)格式的元组。2
:线段的厚度。注:cv2.line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)线段绘制函数其余参数详解如下:
lineType
:线段的类型。这可以是一个常数,例如cv2.LINE_AA表示抗锯齿线型,cv2.LINE_4表示四像素线型。如果没有指定,默认为cv2.LINE_8。shift
:坐标中的小数位数。如果它是正数,那么坐标值将乘以10的幂(例如,如果shift=2,那么坐标值将乘以100)。如果它是负数,那么坐标值将除以10的幂(例如,如果shift=-2,那么坐标值将除以100)。如果没有指定,默认为8。- def drawConvexHull(start,end):
- #将指定的点构成一个凸包,绘制成轮廓,一般眼睛、嘴使用凸包用来绘制
- Facial = shape[start:end+1]
- mouthHull = cv2.convexHull(Facial) # 凸包函数
- cv2.drawContours(image, [mouthHull], -1, (0, 255, 0), 2)
定义函数,该函数接受两个参数(表示点集的开始和结束索引),然后提取这些索引对应的点集,找到这些点的凸包,并在图像上绘制这个凸包。
本文上述已对cv2.convexHull的使用进行了详细解释,不再叙述,在这里对cv2.drawContours使用进行进一步解释,首先,完整函数如下:
cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
各参数详解如下:
contours
: 这是一个轮廓的列表。轮廓可以是多边形的顶点集,其中每个轮廓都是一个嵌套列表。最外层的列表包含所有轮廓,内层的列表表示每个轮廓的多边形顶点。contourIdx
: 这个参数用于选择要在图像上绘制的轮廓。如果它是-1,那么所有轮廓都会被绘制。否则,它应该是一个整数,表示要绘制的轮廓的索引。lineType
: 这个参数用于指定绘制轮廓的类型。可能的值包括8
, 4
, CV_AA
等。默认值是8
。hierarchy
: 这个参数是可选的,通常用于存储轮廓之间的关系。maxLevel
: 这个参数也是可选的,它用于限制绘制的轮廓的层数。如果提供了这个参数,只有层数小于或等于该参数的轮廓才会被绘制。默认值是-1,表示绘制所有的轮廓层。offset
: 这个参数也是可选的,它用于将轮廓偏移到图像上的特定位置。它应该是一个表示偏移量的(x, y)元组。- image=cv2.imread("teacherli.jpg")
- detector = dlib.get_frontal_face_detector()# 构造脸部位置检测器
- faces = detector(image, 0)#检测人脸方框位置
- #读取人脸关键点定位模型
- predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
其中,部分参数详解如下:
detector = dlib.get_frontal_face_detector()
: 构造一个用于检测正面人脸的检测器。这是dlib库提供的一个功能。faces = detector(image, 0)
: 使用上面创建的检测器来检测图像中的人脸。image
是要检测的图像,0
是一个可选的参数,表示在图像中搜索人脸的起始位置。该函数返回一个矩形对象的数组,每个矩形对象代表图像中检测到的一个人脸。predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
: 加载一个预训练的模型,用于预测人脸的68个关键点。这个模型文件通常是通过机器学习训练得到的,可以精确地预测人脸的形状和特征。通过加载一张图像,然后在图像中检测正面的人脸,并使用预训练的模型来预测每个检测到的人脸的68个关键点位置。这在人脸识别、表情分析、动画角色驱动等应用中非常有用。
- for face in faces:# 对检测到的rects,逐个遍历
- shape = predictor(image, face) # 获取关键点
- # 将关键点转换为坐标(x,y)的形式
- shape = np.matrix([[p.x, p.y] for p in shape.parts()])
-
- drawConvexHull(36,41) # 绘制右眼凸包
- drawConvexHull(42,47) # 绘制左眼凸包
- drawConvexHull(48,59) #绘制嘴外部凸包
- drawConvexHull(60,67) # 绘制嘴内部凸包
-
- drawLine(0,17) # 绘制脸颊点线
- drawLine(17,22) # 绘制左眉毛点线
- drawLine(22,27) # 绘制右眉毛点线
- drawLine(27,36) # 绘制鼻子点线
对检测到的人脸进行关键点定位,然后通过先前所定义的关键点绘制函数和线条绘制函数利用这些关键点绘制出眼睛、嘴、脸颊、眉毛和鼻子的凸包和线段。
- import numpy as np
- import dlib
- import cv2
-
- def drawLine(start,end): #将指定的点连接起来
- pts = np.array(shape[start:end]) # 获取点集,并将矩阵matrix数据转换为array数据
- for l in range(1, len(pts)):
- ptA = tuple(pts[l - 1])
- ptB = tuple(pts[l])
- cv2.line(image, ptA, ptB, (0, 255, 0), 2)
-
- def drawConvexHull(start,end):
- #将指定的点构成一个凸包,绘制成轮廓,一般眼睛、嘴使用凸包用来绘制
- Facial = shape[start:end+1]
- mouthHull = cv2.convexHull(Facial) # 凸包函数
- cv2.drawContours(image, [mouthHull], -1, (0, 255, 0), 2)
-
-
- image=cv2.imread("teacherli.jpg")
-
- detector = dlib.get_frontal_face_detector()# 构造脸部位置检测器
- faces = detector(image, 0)#检测人脸方框位置
-
- #读取人脸关键点定位模型
- predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
-
- for face in faces: #获取每一张脸的关键点(实现检测)
- shape=predictor(img, face)# 获取关键点
- # 将关键点转换为坐标(x,y)的形式
- landmarks = np.matrix([[p.x, p.y] for p in shape.parts()])
- #绘制每一张脸的关键点(绘制shape中的每个点)
- for idx, point in enumerate(landmarks):
- pos = (point[0, 0], point[0, 1])# 当前关键的坐标
- # 针对当前关键点,绘制一个实心圆
- cv2.circle(img, pos, 2, color=(0, 255, 0))
- font = cv2.FONT_HERSHEY_SIMPLEX # 字体
- cv2.putText(img, str(idx), pos, font, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
-
- for face in faces:# 对检测到的rects,逐个遍历
- shape = predictor(image, face) # 获取关键点
- # 将关键点转换为坐标(x,y)的形式
- shape = np.matrix([[p.x, p.y] for p in shape.parts()])
-
- drawConvexHull(36,41) # 绘制右眼凸包
- drawConvexHull(42,47) # 绘制左眼凸包
- drawConvexHull(48,59) #绘制嘴外部凸包
- drawConvexHull(60,67) # 绘制嘴内部凸包
-
- drawLine(0,17) # 绘制脸颊点线
- drawLine(17,22) # 绘制左眉毛点线
- drawLine(22,27) # 绘制右眉毛点线
- drawLine(27,36) # 绘制鼻子点线
-
- cv2.imshow("Frame", image)
- cv2.waitKey()
- cv2.destroyAllWindows()
原图如下:
关键点轮廓绘制效果图:
人脸关键点轮廓绘制技术是计算机视觉领域的重要应用之一,未来将继续得到广泛关注和研究。作为学习者,我们需要不断深入学习相关知识,加强实践应用能力,为该领域的发展做出贡献。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。