728x90
반응형
현재 산학연계 현장실습을 진행하면서 맡은 과제가 되게 재미있다.
현재 기업의 비디오월 컨트롤 프로그램에 멀티모달 인터페이스를 추가하는 것이다.
즉, 마우스 또는 키보드 외에 비디오, 오디오 입력을 인식해 시스템을 제어하는 프로그램을 만드는 것이 목표!
그중 첫 번째 단계로, 웹캠을 이용해 손가락 제스처를 인식하여 마우스를 조작하는 기능을 개발하고 있다.
MediaPipe
MediaPipe는 실시간 멀티미디어 애플리케이션을 위한 머신 러닝 파이프라인을 구축할 수 있는 구글의 오픈소스 프레임워크이다.
MediaPipe는 구글에서 개발해서 그런지 다양한 머신 러닝 솔루션들을 제공하고 또 관련 문서도 많았다. 덕분에 개발하는데 많은 도움이 되었음. 특별히 이번 과제에서는 손 랜드마크 감지 기능을 사용하기로 했다.
MediaPipe 사용
pip install mediapipe
손 랜드마크 경우에는 0부터 20까지 총 21개의 손바닥 포인트를 감지한다. 일반적인 웹캠 영상을 사용했을 때에도 상당히 정확도가 높다.
저장된 이미지나 동영상이 아닌 웹캠에서 받아오는 실시간 영상을 감지해서 손을 추적해야 하므로, opencv 라이브러리를 사용해서 읽어 들인 프레임을 MediaPipe에 전달하도록 구성한다.
opencv 라이브러리가 없으면 설치한다.
pip install opencv-python
mediapipe의 랜드마크 트래킹을 이용해 각 손가락이 접혀있는지 판단하고, 취한 제스처를 인식하는 코드를 작성해보았다.
세부적인 내용은 주석 참고!
import cv2
import mediapipe as mp
# Mediapipe 설정
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1, min_detection_confidence=0.5, min_tracking_confidence=0.5)
mp_drawing = mp.solutions.drawing_utils
def get_finger_status(hand):
"""
손가락이 펴져 있는지 접혀 있는지 확인하는 함수
"""
# 오른손만 사용
fingers = []
# 엄지: 랜드마크 4가 랜드마크 2의 오른쪽에 있으면 펼쳐진 상태
if hand.landmark[4].x < hand.landmark[3].x:
fingers.append(1)
else:
fingers.append(0)
# 나머지 손가락: 각 손가락의 팁 (8, 12, 16, 20)이 PIP (6, 10, 14, 18) 위에 있으면 펼쳐진 상태
tips = [8, 12, 16, 20]
pip_joints = [6, 10, 14, 18]
for tip, pip in zip(tips, pip_joints):
if hand.landmark[tip].y < hand.landmark[pip].y:
fingers.append(1)
else:
fingers.append(0)
return fingers
def recognize_gesture(fingers_status):
if fingers_status == [0, 0, 0, 0, 0]:
return 'fist'
elif fingers_status == [0, 1, 0, 0, 0]:
return 'point'
elif fingers_status == [1, 1, 1, 1, 1]:
return 'open'
elif fingers_status == [0, 1, 1, 0, 0]:
return 'peace'
elif fingers_status == [1, 1, 0, 0, 0]:
return 'standby'
# 웹캠 설정
video = cv2.VideoCapture(0)
print("Webcam is running... Press 'ESC' to exit.")
while video.isOpened():
ret, frame = video.read()
if not ret:
break
frame = cv2.flip(frame, 1)
img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
result = hands.process(img_rgb)
if result.multi_hand_landmarks:
for hand_landmarks in result.multi_hand_landmarks:
fingers_status = get_finger_status(hand_landmarks)
print(recognize_gesture(fingers_status))
# 손 랜드마크와 연결선 그리기
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
cv2.imshow('Hand Gesture', frame)
if cv2.waitKey(1) == 27: # ESC 키로 종료
break
video.release()
cv2.destroyAllWindows()
결과물
728x90
반응형
'개발 > Python' 카테고리의 다른 글
[Python/GUI] PySide GUI에서 로딩 GIF 이미지 표시하기 (0) | 2024.08.09 |
---|---|
[Python/ML] 인터넷, API 요청 없이 실시간 음성 인식 구현하기(오프라인 실시간 음성 인식) (작성중) (0) | 2024.08.08 |
[Python] Pyinstaller Mediapipe 컴파일 에러 해결 (1) | 2024.07.16 |