얼굴 추적 카메라

DynamiKontrol에는 얼굴 추적 알고리즘이 포함되어 있지 않습니다. 따라서 Mediapipe의 Face tracking solution을 사용하였고, OpenCV를 사용하여 웹캠을 제어합니다.

설명

_images/face_tracking_cam.jpg

x1, x2 를 각각 얼굴 바운딩 박스의 왼쪽 위 좌표, 오른쪽 아래 좌표라고 가정하고, cx 를 얼굴의 중심 좌표라고 가정합시다. Mediapipe는 좌표를 입력 이미지의 상대 좌표로 반환하므로 cx 의 값 범위는 0.0 에서 1.0 사이가 될 것입니다. 예를 들어 이미지 안에서 얼굴이 정중앙에 위치한다면 cx 의 값은 0.5 가 됩니다.

cx = (x1 + x2) / 2 # center of the face

if cx < 0.4: # left -> clockwise
    angle += ANGLE_STEP
    module.motor.angle(angle)
elif cx > 0.6: # right -> counter clockwise
    angle -= ANGLE_STEP
    module.motor.angle(angle)

만약 cx < 0.4 이면 이미지의 왼쪽에 얼굴이 위치하는 것이고, 카메라는 왼쪽으로 회전해야 합니다. 이것은 모터가 시계방향으로 움직이는 것을 뜻합니다. cx > 0.6 이면 반대로 움직입니다.

소스코드

import cv2
import mediapipe as mp
from dynamikontrol import Module

ANGLE_STEP = 1

module = Module()

mp_drawing = mp.solutions.drawing_utils
mp_face_detection = mp.solutions.face_detection

face_detection = mp_face_detection.FaceDetection(
    min_detection_confidence=0.7)

cap = cv2.VideoCapture(0)
angle = 0 # motor current angle

while cap.isOpened():
    ret, img = cap.read()
    if not ret:
        break

    img = cv2.flip(img, 1) # mirror image

    results = face_detection.process(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    if results.detections:
        for detection in results.detections:
            mp_drawing.draw_detection(img, detection)

            x1 = detection.location_data.relative_bounding_box.xmin # left side of face bounding box
            x2 = x1 + detection.location_data.relative_bounding_box.width # right side of face bounding box

            cx = (x1 + x2) / 2 # center of the face

            if cx < 0.4: # left -> clockwise
                angle += ANGLE_STEP
                module.motor.angle(angle)
            elif cx > 0.6: # right -> counter clockwise
                angle -= ANGLE_STEP
                module.motor.angle(angle)

            cv2.putText(img, '%d deg' % (angle), org=(10, 30), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1, color=255, thickness=2)

            break

    cv2.imshow('Face Cam', img)
    if cv2.waitKey(1) == ord('q'):
        break

cap.release()
face_detection.close()
module.disconnect()