目录
一、关键点定位
1、什么是关键点定位
关键点定位是指在人脸图像中自动定位人脸的关键点,如眼睛、鼻子、嘴巴等特征点。
在dlib中,通过使用预训练的模型 (如shape_predictor_68_face_landmarks.dat )来实现,该模型可以检测并标定68个面部特征点, 这些特征点包括脸颊、眉毛、眼睛、鼻子、嘴巴等部位的关键点,通过它们可以对人脸进行更深入的分析和处理。
2、步骤
1)加载预训练的人脸检测器
使用dlib的get_frontal_face_detector()函数加载预训练的人脸检测器模型。
2)加载预训练的关键点检测器
使用dlib 的shape_predictor()函数加载预训练的关键点检测器模型。
3)读取图像
使用OpenCV的imread()函数读取图像。
4)检测人脸
使用人脸检测器模型 来检测图像中的人脸。调用detector()函数可以返回一个包含人脸位置的矩形列表。
5)关键点检测
对于每个检测到的人脸,使用关键点检测器模型来检测人脸的关键点。调用predictor()函数可以返回一个包含关键点位置的对象。
6)可视化关键点
使用OpenCV的circle()函数,在图像上绘制检测到的关键点。
7)显示图像
使用OpenCV的imshow()函数显示带有关键点的图像。
二、案例实现
1、定位图片关键点
python
import numpy as np
import cv2
import dlib
img = cv2.imread("renlian.png") # 读取图像
detector = dlib.get_frontal_face_detector() # 构造人脸检测器
faces = detector(img,0) # 使用检测器来检测人脸,0表示对图像进行上采样的次数为0
# dlib.shape_predictor载入模型(加获预测器)
# 可以从https://github.com/davisking/dlib-models下载 xmlopencv自己训练好的特征
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 加载预训练模型,用于定位人脸的68个关键点
for face in faces: # 遍历每一张脸,然后在上面绘制关键点
shape = predictor(img,face) # 获取关键点
# 将关键点转换为坐标(x,y)的形式
#landmarks = np.matrix([lp.x,p.y]for p in shape.parts()])
landmarks = np.array([[p.x,p.y] for p in shape.parts()]) # shape.parts()返回一个包含所有人脸关键点的迭代器,遍历出来每张人脸的关键点坐标再传入列表然后将其转换为矩阵类型
for idx, point in enumerate(landmarks): # 使用enumerate将每个关键点的索引和值遍历除去
pos = [point[0], point[1]] # 获取当前关键的坐标
cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1) # 针对当前关键点,绘制一个圆,结尾的-1表示实心圆
# 在关键点旁边标记上对应的索引
cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4,(255, 255, 255),1, cv2.LINE_AA)
cv2.imshow("img",img) # 展示绘制完结图像
cv2.waitKey(0)
cv2.destroyAllWindows()
1)调试模式
2)运行结果
2、摄像头实时定位
python
import numpy as np
import cv2
import dlib
cap = cv2.VideoCapture('笑容.mp4') # 打开视频文件
# cap = cv2.VideoCapture(0) # 调用摄像头
if not cap.isOpened(): # 如果打开失败
print("Cannot open camera")
exit() # 终止程序
detector = dlib.get_frontal_face_detector() # 构造人脸检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") # 导入人脸关键点检测的预训练模型,检测人脸的68个特征点
while True: # 建立死循环,用来不停地读取视频的每一帧画面
ret, img = cap.read() # 读取视频帧,返回读入状态的布尔值和图片,一次读取一帧画面
if not ret: # 读取失败,则退出循环
print("不能读取摄像头")
break
faces = detector(img,0) # 调用人脸检测器,检测人脸
for face in faces: # 获取每一张脸的关键点(实现检测)
shape = predictor(img,face) # 获取关键点
landmarks = np.array([[p.x,p.y] for p in shape.parts()]) # 迭代每个人脸的关键点信息,然后遍历出来增加到列表中去
for idx, point in enumerate(landmarks):
pos = [point[0], point[1]] # 关键点坐标
cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1) # 在每个关键点旁边绘制实心圆圈
cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4,(255, 255, 255),1, cv2.LINE_AA)
cv2.imshow("img",img)
k = cv2.waitKey(20) # 每一帧画面执行20毫秒
if k == 27: # 如果键盘点击esc键,终止循环
break
# 释放资源
cv2.destroyAllWindows()