本代码基于 Advance Computer Vision with Python 进行修改,更加适合中国宝宝体质
我的相关代码及数据集已经上传GitHub仓库,欢迎使用 Advance-Computer-Vision-with-Python
Basics.py
import cv2
import mediapipe as mp
import time
# 打开视频文件
cap = cv2.VideoCapture("E:\\Advance Computer Vision with Python\\main\\Chapter 3 Face Detection\\Videos\\3.mp4")ifnot cap.isOpened():print("Error: Could not open video.")
exit()
pTime =0# 初始化 MediaPipe 的绘图工具和面部网格模型
mpDraw = mp.solutions.drawing_utils # 导入 MediaPipe 的绘图工具模块
mpFaceMesh = mp.solutions.face_mesh # 导入 MediaPipe 的面部网格模块,用于检测和处理面部特征点
faceMesh = mpFaceMesh.FaceMesh(max_num_faces=2)# 初始化面部网格模型,设置最多检测两张人脸
drawSpec = mpDraw.DrawingSpec(thickness=1, circle_radius=2)# 创建一个绘图规格对象,用于定义标志点和连接线的绘制样式# thickness 指定线的厚度,circle_radius 指定标志点的半径whileTrue:print("Reading video frame...")
success, img = cap.read()print("Read success:", success)ifnot success:print("Finished processing video or error occurred.")break# 将图像转换为 RGB
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 处理图像以检测面部网格
results = faceMesh.process(imgRGB)if results.multi_face_landmarks:for faceLms in results.multi_face_landmarks:# 绘制面部网格
mpDraw.draw_landmarks(img, faceLms, mpFaceMesh.FACEMESH_TESSELATION, drawSpec, drawSpec)# mpDraw.draw_landmarks 调用 MediaPipe 的绘图函数,用于在图像上绘制标志点和连接# img: 要在其上绘制标志点的图像# faceLms: 检测到的人脸标志点集合# mpFaceMesh.FACEMESH_TESSELATION: 指定要绘制的连接类型,这里是面部网格的细分连接# drawSpec: 定义标志点和连接线的绘制样式(如厚度和圆圈半径)# 后面两个drawSpec,第一个用于定义标志点(关键点)的绘制样式,比如圆圈的半径和颜色,第二个用于定义连接线的绘制样式,比如线的厚度和颜色# 可以选择分别定义:# drawSpecPoints = mpDraw.DrawingSpec(color=(0, 255, 0), thickness=1, circle_radius=2) # 绿色# drawSpecLines = mpDraw.DrawingSpec(color=(255, 0, 0), thickness=1) # 蓝色# 其中对于drawSpecLines 中定义 circle_radius=2 是没有效果的,circle_radius 只影响标志点(关键点)的绘制,而不会影响连接线的绘制,因此,在 drawSpecLines 中设置 circle_radius 没有意义forid, lm inenumerate(faceLms.landmark):# 获取图像的尺寸
ih, iw, ic = img.shape
x, y =int(lm.x * iw),int(lm.y * ih)# 打印每个标志点的 ID 和坐标print(id, x, y)# 计算并显示帧率
cTime = time.time()
fps =1/(cTime - pTime)
pTime = cTime
cv2.putText(
img,f"FPS: {int(fps)}",(20,70), cv2.FONT_HERSHEY_PLAIN,5,(255,0,0),5)
cv2.namedWindow("Image", cv2.WINDOW_NORMAL)# 创建可调整大小的窗口# 显示图像
cv2.imshow("Image", img)
cv2.waitKey(1)
cap.release()
cv2.destroyAllWindows()
FaceMeshModule.py
import cv2
import mediapipe as mp
import time
classFaceMeshDetector:def__init__(
self, staticMode=False, maxFaces=2, minDetectionCon=0.5, minTrackCon=0.5):# 初始化参数
self.staticMode = staticMode # 是否使用静态模式
self.maxFaces = maxFaces # 最大检测人脸数量
self.minDetectionCon = minDetectionCon # 最小检测置信度
self.minTrackCon = minTrackCon # 最小跟踪置信度# 初始化 MediaPipe 的绘图工具和面部网格模型
self.mpDraw = mp.solutions.drawing_utils # 绘图工具
self.mpFaceMesh = mp.solutions.face_mesh # 面部网格模块# self.faceMesh = self.mpFaceMesh.FaceMesh(# self.staticMode, self.maxFaces, self.minDetectionCon, self.minTrackCon# )
self.faceMesh = self.mpFaceMesh.FaceMesh(
static_image_mode=self.staticMode,
max_num_faces=self.maxFaces,
min_detection_confidence=self.minDetectionCon,
min_tracking_confidence=self.minTrackCon,)
self.drawSpec = self.mpDraw.DrawingSpec(
thickness=1, circle_radius=2)# 绘图规格deffindFaceMesh(self, img, draw=True):# 将图像转换为 RGB
self.imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 处理图像以检测面部网格
self.results = self.faceMesh.process(self.imgRGB)
faces =[]# 存储检测到的面部特征点if self.results.multi_face_landmarks:for faceLms in self.results.multi_face_landmarks:if draw:# 绘制面部网格
self.mpDraw.draw_landmarks(
img,
faceLms,
self.mpFaceMesh.FACEMESH_TESSELATION,
self.drawSpec,
self.drawSpec,)
face =[]# 存储单个人脸的特征点forid, lm inenumerate(faceLms.landmark):
ih, iw, ic = img.shape # 获取图像的高、宽、通道数
x, y =int(lm.x * iw),int(lm.y * ih)# 将归一化坐标转换为像素坐标
face.append([x, y])# 添加特征点坐标
faces.append(face)# 添加到面部列表return img, faces # 返回图像和面部特征点defmain():# 打开视频文件
cap = cv2.VideoCapture("E:\\Advance Computer Vision with Python\\main\\Chapter 3 Face Detection\\Videos\\4.mp4")
pTime =0# 上一帧的时间
detector = FaceMeshDetector(maxFaces=2)# 初始化面部网格检测器whileTrue:
success, img = cap.read()ifnot success:break
img, faces = detector.findFaceMesh(img)# 检测面部网格iflen(faces)!=0:print(faces[0])# 打印第一个面部的特征点
cTime = time.time()# 当前时间
fps =1/(cTime - pTime)# 计算帧率
pTime = cTime # 更新上一帧的时间
cv2.putText(
img,f"FPS: {int(fps)}",(20,70), cv2.FONT_HERSHEY_PLAIN,3,(0,255,0),3)# 在图像上显示帧率
cv2.namedWindow("Image", cv2.WINDOW_NORMAL)# 创建可调整大小的窗口
cv2.imshow("Image", img)# 显示图像
cv2.waitKey(1)# 等待键盘输入if __name__ =="__main__":
main()
mp.solutions.face_mesh
mpFaceMesh = mp.solutions.face_mesh
导入 MediaPipe 的面部网格模块,用于检测和处理面部特征点
faceMesh = mpFaceMesh.FaceMesh(max_num_faces=2)
初始化面部网格模型,设置最多检测两张人脸
results = faceMesh.process(imgRGB)
处理图像以检测面部网格
mpFaceMesh.FaceMesh()
类的参数有:self.staticMode, self.maxFaces, self.minDetectionCon, self.minTrackCon
- staticMode:是否将每帧图像作为静态图像处理。如果为 True,每帧都会进行人脸检测;如果为 False,在检测到人脸后进行跟踪,速度更快
- maxFaces:要检测的最大人脸数量
- minDetectionCon:检测的最小置信度阈值。低于此值的人脸将被忽略
- minTrackCon:跟踪的最小置信度阈值。低于此值的跟踪将被忽略
mp.solutions.drawing_utils
mpDraw = mp.solutions.drawing_utils
导入 MediaPipe 的绘图工具模块
drawSpec = mpDraw.DrawingSpec(thickness=1, circle_radius=2)
创建一个绘图规格对象,用于定义标志点和连接线的绘制样式,thickness 指定线的厚度,circle_radius 指定标志点的半径
mpDraw.draw_landmarks(img, faceLms, mpFaceMesh.FACEMESH_TESSELATION, drawSpec, drawSpec)
mpDraw.draw_landmarks 调用 MediaPipe 的绘图函数,用于在图像上绘制标志点和连接
- img: 要在其上绘制标志点的图像
- faceLms: 检测到的人脸标志点集合
- mpFaceMesh.FACEMESH_TESSELATION: 指定要绘制的连接类型,这里是面部网格的细分连接
- drawSpec: 定义标志点和连接线的绘制样式(如厚度和圆圈半径),后面两个drawSpec,第一个用于定义标志点(关键点)的绘制样式,比如圆圈的半径和颜色,第二个用于定义连接线的绘制样式,比如线的厚度和颜色
源代码的小问题
这些bug直接运行是不会报错的,只有调试的时候才会报错
1、有个参数在新版本换名字了
原来:
现在:
2、有个位置传参需要修改成关键字传参
版权归原作者 Dirawww 所有, 如有侵权,请联系我们删除。