文章目录
- dlib库是什么?
- OpenCV库与dlib库对比
- dlib库安装
- dlib——人脸应用实例——人脸检测
- dlib——人脸应用实例——人脸关键点定位
- dlib——人脸应用实例——人脸轮廓绘制
dlib库是什么?
OpenCV库与dlib库对比
dlib库安装
dlib——人脸应用实例——人脸检测
对图片中的人脸进行检测:
代码:
# 导入OpenCV库,它是一个广泛用于计算机视觉任务的库,可用于图像读取、处理和显示等操作
import cv2
# 导入dlib库,dlib是一个强大的机器学习工具包,提供了多种人脸检测和特征提取的功能
import dlib# 创建一个dlib的人脸检测器对象
# get_frontal_face_detector() 是dlib提供的预训练好的人脸检测器,用于检测图像中的人脸
detector = dlib.get_frontal_face_detector()# 使用OpenCV的imread函数读取指定路径的图像文件
# 'hezhao.jpg' 是图像文件的路径,这里假设该图像文件与代码文件在同一目录下
# 读取后的图像以NumPy数组的形式存储在变量 img 中
img = cv2.imread('hezhao.jpg')# 使用人脸检测器对读取的图像进行人脸检测
# 第二个参数 2 表示对图像进行2次上采样,上采样可以提高小尺寸人脸的检测精度,但会增加计算量
# 检测结果存储在变量 faces 中,它是一个包含所有检测到的人脸区域的列表
faces = detector(img, 2)# 遍历检测到的所有人脸
for face in faces:# 获取当前人脸区域的左边界坐标x1 = face.left()# 获取当前人脸区域的上边界坐标y1 = face.top()# 获取当前人脸区域的右边界坐标x2 = face.right()# 获取当前人脸区域的下边界坐标y2 = face.bottom()# 使用OpenCV的rectangle函数在图像上绘制矩形框来标记检测到的人脸# 第一个参数 img 是要绘制矩形框的图像# 第二个参数 (x1, y1) 是矩形框的左上角坐标# 第三个参数 (x2, y2) 是矩形框的右下角坐标# 第四个参数 (0, 255, 0) 表示矩形框的颜色,这里是绿色(BGR格式)# 第五个参数 2 表示矩形框的线宽cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)# 使用OpenCV的imshow函数显示处理后的图像
# 第一个参数 'result' 是显示图像的窗口名称
# 第二个参数 img 是要显示的图像
cv2.imshow('result', img)# 使用OpenCV的waitKey函数等待用户按键
# 参数 0 表示无限等待,直到用户按下任意键
cv2.waitKey(0)# 使用OpenCV的destroyAllWindows函数关闭所有由OpenCV打开的窗口
cv2.destroyAllWindows()
结果:
也可对视频或使用摄像头中的人脸识别:
代码:
# 导入OpenCV库,它是一个强大的计算机视觉库,可用于视频捕获、图像处理和显示等操作
import cv2
# 导入dlib库,dlib是一个机器学习工具包,提供了预训练的人脸检测模型
import dlib# 创建一个dlib的人脸检测器对象,用于检测图像或视频帧中的人脸
# get_frontal_face_detector() 是dlib提供的预训练好的正面人脸检测器
detector = dlib.get_frontal_face_detector()# 使用OpenCV的VideoCapture函数打开默认摄像头(设备编号为0)
# cap 是一个VideoCapture对象,用于后续读取视频帧
cap = cv2.VideoCapture(0)# 进入一个无限循环,持续处理摄像头捕获的视频帧
while True:# 从摄像头读取一帧视频# ret 是一个布尔值,表示是否成功读取到视频帧# image 是读取到的视频帧,以NumPy数组的形式存储ret, image = cap.read()# 对读取的视频帧进行水平翻转# 第二个参数 1 表示水平翻转,这样可以让画面看起来更符合我们的习惯img = cv2.flip(image, 1)# 如果 ret 为 None 或者 False,说明没有成功读取到视频帧# 这种情况可能是由于摄像头断开连接、视频结束等原因导致的# 此时跳出循环,结束程序if ret is None:break# 使用人脸检测器对当前视频帧进行人脸检测# 第二个参数 1 表示对图像进行1次上采样,上采样可以提高小尺寸人脸的检测精度,但会增加计算量# faces 是一个包含所有检测到的人脸区域的列表faces = detector(img, 1)# 遍历检测到的所有人脸for face in faces:# 获取当前人脸区域的左边界坐标x1 = face.left()# 获取当前人脸区域的上边界坐标y1 = face.top()# 获取当前人脸区域的右边界坐标x2 = face.right()# 获取当前人脸区域的下边界坐标y2 = face.bottom()# 在视频帧上绘制矩形框来标记检测到的人脸# 第一个参数 img 是要绘制矩形框的图像# 第二个参数 (x1, y1) 是矩形框的左上角坐标# 第三个参数 (x2, y2) 是矩形框的右下角坐标# 第四个参数 (0, 255, 0) 表示矩形框的颜色,这里是绿色(BGR格式)# 第五个参数 2 表示矩形框的线宽cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)# 显示处理后的视频帧# 第一个参数 'result' 是显示窗口的名称# 第二个参数 img 是要显示的视频帧cv2.imshow('result', img)# 等待用户按键,等待时间为1毫秒# key 是用户按下键的ASCII码值key = cv2.waitKey(1)# 如果用户按下的键是ESC键(ASCII码值为27)# 则跳出循环,结束程序if key == 27:break# 释放摄像头资源,关闭摄像头设备
cap.release()# 关闭所有由OpenCV打开的窗口
cv2.destroyAllWindows()
dlib——人脸应用实例——人脸关键点定位
通过https://github.com/davisking/dlib-models下载所需要的预训练模型,对图片进行人脸关键点定位。读取一张图像,检测其中的人脸,并在每个人脸的 68 个特征点上绘制绿色圆形标记,同时在标记旁边显示特征点的索引编号,最后显示处理后的图像。
代码:
# 导入NumPy库,用于进行高效的数值计算,这里主要用于处理面部特征点的数组
import numpy as np
# 导入OpenCV库,用于图像处理和计算机视觉任务,如读取图像、绘制图形和显示图像等
import cv2
# 导入dlib库,它是一个强大的机器学习库,这里主要用于人脸检测和面部特征点定位
import dlib# 使用OpenCV的imread函数读取指定路径的图像文件,将其存储为一个NumPy数组
# "c_luo1.png" 是图像文件的路径,你可以根据实际情况修改
img = cv2.imread("c_luo1.png")# 创建一个dlib的人脸检测器对象,用于检测图像中的人脸
# get_frontal_face_detector() 是dlib提供的一个预训练的人脸检测器
detector = dlib.get_frontal_face_detector()# 使用人脸检测器对输入图像进行人脸检测
# 第二个参数0表示不进行图像的上采样,若为正数则会对图像进行上采样以提高检测精度,但会增加计算量
faces = detector(img, 0)# 创建一个dlib的面部特征点预测器对象,用于定位人脸的68个特征点
# 'shape_predictor_68_face_landmarks.dat' 是预训练的特征点预测模型文件,需要提前下载
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')# 遍历检测到的所有人脸
for face in faces:# 使用面部特征点预测器对当前人脸进行特征点定位# 输入参数为图像和检测到的人脸区域shape = predictor(img, face)# 将dlib的特征点对象转换为NumPy数组,方便后续处理# shape.parts() 返回一个包含68个特征点的对象,每个特征点有x和y坐标# 通过列表推导式将每个特征点的x和y坐标提取出来,存储为一个二维NumPy数组landmarks = np.array([[p.x, p.y] for p in shape.parts()])# 遍历每个特征点for idx, point in enumerate(landmarks):# 提取当前特征点的x和y坐标,存储为一个列表pos = [point[0], point[1]]# 使用OpenCV的circle函数在图像上绘制一个圆形标记特征点# img 是要绘制的图像,pos 是圆心坐标,2 是圆的半径# color=(0, 255, 0) 表示圆的颜色为绿色,thickness=-1 表示填充整个圆形cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1)# 使用OpenCV的putText函数在特征点旁边绘制特征点的索引编号# str(idx) 是要绘制的文本,即特征点的索引编号# pos 是文本的起始位置,cv2.FONT_HERSHEY_SIMPLEX 是字体样式# 0.4 是字体大小,(255, 255, 255) 是文本颜色为白色# 1 是文本的线宽,cv2.LINE_AA 表示使用抗锯齿线以提高文本的绘制质量cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4,(255, 255, 255), 1, cv2.LINE_AA)# 使用OpenCV的imshow函数显示处理后的图像
# 'img' 是窗口的名称,img 是要显示的图像
cv2.imshow('img', img)# 使用OpenCV的waitKey函数等待用户按键
# 参数0表示无限等待,直到用户按下任意键
cv2.waitKey(0)# 使用OpenCV的destroyAllWindows函数关闭所有打开的窗口
cv2.destroyAllWindows()
结果:
也可以对视频或者使用摄像头直接识别人脸然后直接进行人脸关键点的定位:
代码:
# 导入NumPy库,它是Python中用于科学计算的基础库,这里主要用于处理数组数据,比如面部特征点的坐标数组
import numpy as np
# 导入OpenCV库,这是一个强大的计算机视觉库,用于视频捕获、图像处理、绘制图形等操作
import cv2
# 导入dlib库,它是一个机器学习工具包,提供了很多用于人脸检测和特征点定位的预训练模型
import dlib# 使用cv2.VideoCapture函数打开默认的摄像头(设备编号为0),返回一个VideoCapture对象
# 后续可以通过该对象读取摄像头的视频帧
cap = cv2.VideoCapture(0)# 创建一个dlib的面部特征点预测器对象
# 'shape_predictor_68_face_landmarks.dat' 是预训练好的模型文件,用于检测人脸的68个特征点
# 这个文件需要提前下载并放在代码可访问的路径下
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')# 创建一个dlib的人脸检测器对象
# get_frontal_face_detector() 是dlib提供的一个预训练的人脸检测器,用于在图像中检测人脸
detector = dlib.get_frontal_face_detector()# 进入一个无限循环,持续读取摄像头的视频帧并进行处理
while True:# 使用cap.read()方法从摄像头读取一帧视频# ret 是一个布尔值,表示是否成功读取到视频帧# image 是读取到的视频帧,是一个NumPy数组ret, image = cap.read()# 使用cv2.flip函数对读取到的视频帧进行水平翻转# 第二个参数1表示水平翻转,这样可以让画面看起来更符合我们的习惯img = cv2.flip(image, 1)# 如果ret为False,说明没有成功读取到视频帧,可能是摄像头断开连接等原因# 此时跳出循环,结束程序if ret is None:break# 使用人脸检测器对当前视频帧进行人脸检测# 第二个参数0表示不进行图像的上采样,若为正数则会对图像进行上采样以提高检测精度,但会增加计算量faces = detector(img, 0)# 遍历检测到的所有人脸for face in faces:# 使用面部特征点预测器对当前人脸进行特征点定位# 输入参数为当前视频帧和检测到的人脸区域shape = predictor(img, face)# 将dlib的特征点对象转换为NumPy数组,方便后续处理# shape.parts() 返回一个包含68个特征点的对象,每个特征点有x和y坐标# 通过列表推导式将每个特征点的x和y坐标提取出来,存储为一个二维NumPy数组landmarks = np.array([[p.x, p.y] for p in shape.parts()])# 遍历每个特征点for idx, point in enumerate(landmarks):# 提取当前特征点的x和y坐标,存储为一个列表pos = [point[0], point[1]]# 使用cv2.circle函数在图像上绘制一个圆形标记特征点# img 是要绘制的图像,pos 是圆心坐标,2 是圆的半径# color=(0, 255, 0) 表示圆的颜色为绿色,thickness=-1 表示填充整个圆形cv2.circle(img, pos, 2, color=(0, 255, 0), thickness=-1)# 使用cv2.putText函数在特征点旁边绘制特征点的索引编号# str(idx) 是要绘制的文本,即特征点的索引编号# pos 是文本的起始位置,cv2.FONT_HERSHEY_SIMPLEX 是字体样式# 0.4 是字体大小,(255, 255, 255) 是文本颜色为白色# 1 是文本的线宽,cv2.LINE_AA 表示使用抗锯齿线以提高文本的绘制质量cv2.putText(img, str(idx), pos, cv2.FONT_HERSHEY_SIMPLEX, 0.4,(255, 255, 255), 1, cv2.LINE_AA)# 使用cv2.imshow函数显示处理后的视频帧# 'img' 是窗口的名称,img 是要显示的图像cv2.imshow('img', img)# 使用cv2.waitKey函数等待用户按键,参数1表示等待1毫秒# 返回值key是用户按下键的ASCII码值key = cv2.waitKey(1)# 如果用户按下的键是ESC键(ASCII码值为27),则跳出循环,结束程序if key == 27:break# 释放摄像头资源,关闭摄像头设备
cap.release()# 关闭所有由OpenCV打开的窗口
cv2.destroyAllWindows()
可以自己进行尝试,也可从网站下载其他功能的预训练模型进行测试
dlib——人脸应用实例——人脸轮廓绘制
对人脸的轮廓进行绘制是基于关键点检测的基础上进行的,更能体现出人脸的特征与表情变化。
代码:
# 导入NumPy库,用于高效处理多维数组和矩阵运算,这里主要用于处理面部特征点的坐标数据
import numpy as np
# 导入OpenCV库,用于图像处理、绘制图形和显示图像等操作
import cv2
# 导入dlib库,它是一个机器学习工具包,提供了人脸检测和面部特征点定位的功能
import dlib# 定义一个函数,用于在图像上绘制线段,连接一系列面部特征点
def drawLine(start, end):# 从shape数组中提取从start到end(不包含end)的特征点pts = shape[start:end]# 遍历提取的特征点for l in range(1, len(pts)):# 获取前一个特征点的坐标,并转换为元组形式ptA = tuple(pts[l - 1])# 获取当前特征点的坐标,并转换为元组形式ptB = tuple(pts[l])# 使用OpenCV的line函数在图像上绘制从ptA到ptB的线段# img是要绘制的图像,ptA和ptB是线段的起点和终点,(0, 255, 0)是线段的颜色(绿色),2是线段的线宽cv2.line(img, ptA, ptB, (0, 255, 0), 2)# 定义一个函数,用于在图像上绘制凸包,连接一系列面部特征点形成封闭的凸多边形
def drawConvexHull(start, end):# 从shape数组中提取从start到end(包含end)的特征点Facial = shape[start:end + 1]# 使用OpenCV的convexHull函数计算这些特征点的凸包mouthHull = cv2.convexHull(Facial)# 使用OpenCV的drawContours函数在图像上绘制凸包轮廓# img是要绘制的图像,[mouthHull]是包含凸包轮廓的列表,-1表示绘制所有轮廓,(0, 255, 0)是轮廓的颜色(绿色),2是轮廓的线宽cv2.drawContours(img, [mouthHull], -1, (0, 255, 0), 2)# 使用OpenCV的imread函数读取指定路径的图像文件
# "c_luo1.png" 是图像文件的路径,你可以根据实际情况修改
img = cv2.imread("c_luo1.png")
# 创建一个dlib的人脸检测器对象,用于检测图像中的人脸
detector = dlib.get_frontal_face_detector()
# 使用人脸检测器对输入图像进行人脸检测
# 第二个参数0表示不进行图像的上采样,若为正数则会对图像进行上采样以提高检测精度,但会增加计算量
faces = detector(img, 0)
# 创建一个dlib的面部特征点预测器对象,用于定位人脸的68个特征点
# 'shape_predictor_68_face_landmarks.dat' 是预训练的特征点预测模型文件,需要提前下载
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')# 遍历检测到的所有人脸
for face in faces:# 使用面部特征点预测器对当前人脸进行特征点定位shape = predictor(img, face)# 将dlib的特征点对象转换为NumPy数组,方便后续处理# shape.parts() 返回一个包含68个特征点的对象,每个特征点有x和y坐标# 通过列表推导式将每个特征点的x和y坐标提取出来,存储为一个二维NumPy数组shape = np.array([[p.x, p.y] for p in shape.parts()])# 绘制左眼的凸包drawConvexHull(36, 41)# 绘制右眼的凸包drawConvexHull(42, 47)# 绘制外嘴唇的凸包drawConvexHull(48, 59)# 绘制内嘴唇的凸包drawConvexHull(60, 67)# 绘制下巴的线段drawLine(0, 16)# 绘制左眉毛的线段drawLine(17, 21)# 绘制右眉毛的线段drawLine(22, 26)# 绘制鼻子的线段drawLine(27, 35)# 使用OpenCV的imshow函数显示处理后的图像
# 'img' 是窗口的名称,img 是要显示的图像
cv2.imshow('img', img)
# 使用OpenCV的waitKey函数等待用户按键
# 参数0表示无限等待,直到用户按下任意键
cv2.waitKey(0)
# 使用OpenCV的destroyAllWindows函数关闭所有打开的窗口
cv2.destroyAllWindows()
对视频内容进行处理的代码:
# 导入NumPy库,用于进行高效的数值计算和数组操作,后续会用来处理面部特征点的坐标数据
import numpy as np
# 导入OpenCV库,这是一个强大的计算机视觉库,可用于视频捕获、图像处理、绘制图形等操作
import cv2
# 导入dlib库,它是一个机器学习工具包,提供了预训练的人脸检测和面部特征点定位模型
import dlib# 定义一个函数,用于在图像上绘制一系列线段,连接指定范围内的面部特征点
def drawLine(start, end):# 从 shape 数组中提取从 start 到 end(不包含 end)索引位置的特征点pts = shape[start:end]# 遍历提取的特征点,从第二个点开始for l in range(1, len(pts)):# 获取前一个特征点的坐标,并将其转换为元组形式,因为 cv2.line 函数要求坐标为元组ptA = tuple(pts[l - 1])# 获取当前特征点的坐标,并将其转换为元组形式ptB = tuple(pts[l])# 在图像 img 上绘制从 ptA 到 ptB 的线段# (0, 255, 0) 表示线段的颜色为绿色(在OpenCV中颜色采用BGR格式),2 表示线段的线宽cv2.line(img, ptA, ptB, (0, 255, 0), 2)# 定义一个函数,用于在图像上绘制凸包,连接指定范围内的面部特征点形成封闭的凸多边形
def drawConvexHull(start, end):# 从 shape 数组中提取从 start 到 end(包含 end)索引位置的特征点Facial = shape[start:end + 1]# 使用 cv2.convexHull 函数计算这些特征点的凸包,返回一个包含凸包顶点坐标的数组mouthHull = cv2.convexHull(Facial)# 在图像 img 上绘制凸包轮廓# [mouthHull] 表示要绘制的轮廓列表,-1 表示绘制所有轮廓,(0, 255, 0) 是轮廓颜色(绿色),2 是轮廓线宽cv2.drawContours(img, [mouthHull], -1, (0, 255, 0), 2)# 打开默认的摄像头设备(设备编号为 0),返回一个 VideoCapture 对象,用于后续视频帧的读取
cap = cv2.VideoCapture(0)
# 创建一个 dlib 的面部特征点预测器对象,使用预训练的 68 点面部特征模型文件
# 该文件需要提前下载并放在代码可访问的路径下
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
# 创建一个 dlib 的人脸检测器对象,用于检测图像或视频帧中的人脸
detector = dlib.get_frontal_face_detector()# 进入一个无限循环,持续处理摄像头捕获的视频帧
while True:# 从摄像头读取一帧视频# ret 是一个布尔值,表示是否成功读取到视频帧# image 是读取到的视频帧,以 NumPy 数组的形式存储ret, image = cap.read()# 对读取的视频帧进行水平翻转,这样可以让画面看起来更符合我们的习惯img = cv2.flip(image, 1)# 如果 ret 为 None 或者 False,说明没有成功读取到视频帧# 可能是摄像头断开连接等原因,此时跳出循环,结束程序if ret is None:break# 使用人脸检测器对当前视频帧进行人脸检测# 第二个参数 0 表示不进行图像的上采样,若为正数则会对图像进行上采样以提高检测精度,但会增加计算量faces = detector(img, 0)# 遍历检测到的所有人脸for face in faces:# 使用面部特征点预测器对当前人脸进行特征点定位shape = predictor(img, face)# 将 dlib 的特征点对象转换为 NumPy 数组,方便后续处理# shape.parts() 返回一个包含 68 个特征点的对象,每个特征点有 x 和 y 坐标# 通过列表推导式将每个特征点的 x 和 y 坐标提取出来,存储为一个二维 NumPy 数组shape = np.array([[p.x, p.y] for p in shape.parts()])# 绘制左眼的凸包drawConvexHull(36, 41)# 绘制右眼的凸包drawConvexHull(42, 47)# 绘制外嘴唇的凸包drawConvexHull(48, 59)# 绘制内嘴唇的凸包drawConvexHull(60, 67)# 绘制下巴的线段drawLine(0, 16)# 绘制左眉毛的线段drawLine(17, 21)# 绘制右眉毛的线段drawLine(22, 26)# 绘制鼻子的线段drawLine(27, 35)# 在窗口中显示处理后的视频帧,窗口名称为 'img'cv2.imshow('img', img)# 等待用户按键,等待时间为 1 毫秒# key 是用户按下键的 ASCII 码值key = cv2.waitKey(1)# 如果用户按下的键是 ESC 键(ASCII 码值为 27),则跳出循环,结束程序if key == 27:break# 释放摄像头资源,关闭摄像头设备
cap.release()
# 关闭所有由 OpenCV 打开的窗口
cv2.destroyAllWindows()