Day11 虛擬面具
🟡 先看看程式的效果
今天的程式利用 OpenCV 和 MediaPipe 模組來進行即時的面部偵測,並將一個面具圖像疊加在偵測到的面部上。這是一個互動性強且有趣的項目,適合初學者加深對電腦視覺的理解。
Today’s program utilizes OpenCV and MediaPipe modules for real-time facial detection and overlays a mask image on the detected face. This is an interactive and fun project, suitable for beginners to deepen their understanding of computer vision.
🟡 學習目標
體驗如何從攝像頭獲取即時影像, 並在影像上進行即時處理和顯示。
通過將面具疊加在偵測到的面部上, 大家可以發揮創意, 製作出有趣的應用效果, 從而激發更多的學習興趣。
🟡 程式碼
請先下載 “Day11 虛擬面具” 資料夾內的程式以及圖檔。
請按此下載
'''
Python + AI in 21 days
https://jasonworkshop.com/python
Designed by Jason Workshop
[請勿修改以上內容]
---
預備工作:
首先,請確保已安裝 opencv-python, mediapipe 模組
如不確定可直接在 Windows 的 cmd prompt 執行以下指定
pip install opencv-python mediapipe
'''
import cv2
import cvzone
import mediapipe as mp
# 初始化 MediaPipe Face Detection 模組
mp_face_detection = mp.solutions.face_detection
face_detection = mp_face_detection.FaceDetection(min_detection_confidence=0.5) # min_detection_confidence 為最低可信度
mp_drawing = mp.solutions.drawing_utils
# 讀取圖檔
mask01 = cv2.imread("mask01.png", cv2.IMREAD_UNCHANGED)
topXAdjust = 0
topYAdjust = -0.45
# 開啟攝影機
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 轉換 BGR 圖像到 RGB
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 偵測面部
result = face_detection.process(rgb_frame)
# 繪製面部位置
if result.detections:
for detection in result.detections:
'''
mp_drawing.draw_detection(
frame,
detection,
keypoint_drawing_spec=mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
bbox_drawing_spec=mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=1))
'''
# 取得關鍵點的座標
'''
keypoint = detection.location_data.relative_keypoints[0]
keypoint_x = int(keypoint.x * frame.shape[1])
keypoint_y = int(keypoint.y * frame.shape[0])
print(f"Keypoint 0: ({keypoint_x}, {keypoint_y})")
'''
# 取得邊界框的相對座標
bbox = detection.location_data.relative_bounding_box
bbox_xmin = int(bbox.xmin * frame.shape[1])
bbox_ymin = int(bbox.ymin * frame.shape[0])
bbox_width = int(bbox.width * frame.shape[1])
bbox_height = int(bbox.height * frame.shape[0])
bbox_xmax = bbox_xmin + bbox_width
bbox_ymax = bbox_ymin + bbox_height
#print(f"BBox Top-Left: ({bbox_xmin}, {bbox_ymin}), Bottom-Right: ({bbox_xmax}, {bbox_ymax})")
# 改變面具大小
width_scale = bbox_width / cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height_scale = bbox_height / cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
mask01b = cv2.resize(mask01, (0,0), None, width_scale * 1.65, height_scale * 1.4)
# 改變面具位置
imgResult = cvzone.overlayPNG(frame, mask01b, [int(bbox_xmin + bbox_xmin * topXAdjust),int(bbox_ymin + bbox_ymin * topYAdjust)])
# 顯示圖像
cv2.imshow('Face Detection', frame)
if cv2.waitKey(1) & 0xFF == 27: # 按下 ESC 鍵退出
break
# 釋放攝影機並關閉所有視窗
cap.release()
cv2.destroyAllWindows()
🟡 小小挑戰一下
大家可以嘗試進行一些修改或改良喔! 例如:
✌️嘗試更換不同的面具吧。
😁 明天見!