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()

🟡 小小挑戰一下

大家可以嘗試進行一些修改或改良喔! 例如:
✌️嘗試更換不同的面具吧。

😁 明天見!

按這裏回到 Python + AI 的 21 天挑戰