Mediapipe 人脸侦测 ( 旧 )
这篇教学会使用 MediaPipe 的人脸侦测模型 ( Face Detection ) 侦测人脸,再透过 OpenCV 读取摄影镜头图像进行侦测,最后也会介绍如何取得五官座标信息,使用绘制形状的方式,即时在摄影画面加上卡通的眼睛。
MidoaPipe 在 2023 年进行了比较大的改版和更新,虽然旧版的程序“可能”还可以运行,但建议使用新版,参考:Mediapipe 人脸侦测 Face Detection ( 2023 年版 )
快速导览:
因为程序使用 Jupyter 搭配 Tensorflow 进行开发,所以请先阅读“使用 Anaconda”和“使用 MediaPipe”,安装对应的软件包,如果不要使用 Juputer,也可参考“使用 Python 虚拟环境”,建立虚拟环境进行实作。
使用 MediaPipe,侦测人脸
下方的程序码延伸“读取并播放影片”文章的范例,搭配 mediapipe 侦测人脸的方法,透过摄影镜头获取图像后,使用白色外框正方形标记人脸,使用红色小圆点标记五官位置。
import cv2
import mediapipe as mp # 載入 mediapipe 函式庫
cap = cv2.VideoCapture(0)
mp_face_detection = mp.solutions.face_detection # 建立偵測方法
mp_drawing = mp.solutions.drawing_utils # 建立繪圖方法
with mp_face_detection.FaceDetection( # 開始偵測人臉
model_selection=0, min_detection_confidence=0.5) as face_detection:
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, img = cap.read()
if not ret:
print("Cannot receive frame")
break
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 將 BGR 顏色轉換成 RGB
results = face_detection.process(img2) # 偵測人臉
if results.detections:
for detection in results.detections:
mp_drawing.draw_detection(img, detection) # 標記人臉
cv2.imshow('oxxostudio', img)
if cv2.waitKey(5) == ord('q'):
break # 按下 q 鍵停止
cap.release()
cv2.destroyAllWindows()
取得五官座标,绘制形状
延伸上方的程序码,在 detection 的 for 循环里,可以取得每个红色小点的座标,由于座标的意义为该位置在水平或垂直方向的“比例”,所以要额外乘以长宽尺寸才会是正确的座标值,取得座标值后,就能利用 OpenCV 绘制形状的方式绘制形状,下面的程序码,会将人脸的两个眼睛,加上卡通的眼睛效果。
import cv2
import mediapipe as mp
cap = cv2.VideoCapture(0)
mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils
with mp_face_detection.FaceDetection(
model_selection=0, min_detection_confidence=0.5) as face_detection:
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, img = cap.read()
if not ret:
print("Cannot receive frame")
break
size = img.shape # 取得攝影機影像尺寸
w = size[1] # 取得畫面寬度
h = size[0] # 取得畫面高度
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
results = face_detection.process(img2)
if results.detections:
for detection in results.detections:
mp_drawing.draw_detection(img, detection)
s = detection.location_data.relative_bounding_box # 取得人臉尺寸
eye = int(s.width*w*0.1) # 計算眼睛大小 ( 人臉尺寸*0.1 )
a = detection.location_data.relative_keypoints[0] # 取得左眼座標
b = detection.location_data.relative_keypoints[1] # 取得右眼座標
ax, ay = int(a.x*w), int(a.y*h) # 計算左眼真正的座標
bx, by = int(b.x*w), int(b.y*h) # 計算右眼真正的座標
cv2.circle(img,(ax,ay),(eye+10),(255,255,255),-1) # 畫左眼白色大圓 ( 白眼球 )
cv2.circle(img,(bx,by),(eye+10),(255,255,255),-1) # 畫右眼白色大圓 ( 白眼球 )
cv2.circle(img,(ax,ay),eye,(0,0,0),-1) # 畫左眼黑色大圓 ( 黑眼球 )
cv2.circle(img,(bx,by),eye,(0,0,0),-1) # 畫右眼黑色大圓 ( 黑眼球 )
cv2.circle(img,(ax-8,ay-8),(eye-15),(255,255,255),-1) # 畫左眼白色小圓 ( 反光 )
cv2.circle(img,(bx-8,by-8),(eye-15),(255,255,255),-1) # 畫右眼白色小圓 ( 反光 )
cv2.imshow('oxxostudio', img)
if cv2.waitKey(5) == ord('q'):
break # 按下 q 鍵停止
cap.release()
cv2.destroyAllWindows()
微信扫码关注
抖音扫码关注