인공지능 기초 수업
Mediapipe hands 모델 왼손, 오른손 구별 하기.
SwMaker_Jun
2025. 4. 15. 12:00
728x90
반응형
1. 핸즈 모델 오픈소스 활용
아래 미디어파이프 핸즈 기본 오픈소스 모델을 이해하고 이번에는 왼손과 오른손을 구별하는 코드를 실습해 보자
https://swmakerjun.tistory.com/55
미디어 파이프 핸즈
1. 핸즈 모델 활용하기. 미디어파이프는 구글에서 개발한 오픈소스 미디어 처리 프레임워크로, 비디오 및 오디오 데이터의 실시간 처리와 기계 학습을 위한 강력한 도구를 제공합니다. 미디어파
swmakerjun.tistory.com
2. 왼손일까? 오른손일까?
– MediaPipe Hands 코드에 ‘왼손/오른손 구별 기능’을 넣어보자!
오늘은 우리가 평소에 수업 시간이나 프로젝트에서 많이 사용하는 MediaPipe Hands 오픈소스를 가지고
조금 더 똑똑하게 바꿔보는 방법을 알아보려고 해요.
바로, “이 손이 왼손인지, 오른손인지” 컴퓨터가 스스로 알아보게 하는 기능이에요!
✅ 기본 코드에서 아래 코드들을 수정해 보자
- 웹캠을 켜고
- 손을 인식하고
- 손가락의 21개 포인트(랜드마크)를 화면에 표시
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
이렇게 간단하게 손 모양을 인식해주는 코드예요.
그런데 한 가지 아쉬운 점이 있어요.
❓"이게 왼손인지? 오른손인지?"는 알려주지 않아요.
3. 우리가 추가한 ‘왼손/오른손 인식’ 기능은 뭐가 다를까요?
우리는 여기에 딱 두 줄 정도의 정보만 추가했어요!
label = handedness.classification[0].label # 'Left' 또는 'Right'
score = handedness.classification[0].score # 신뢰도 (0~1)
예를 들어 / Right (0.97) ← 오른손이고, 97% 확신, Left (0.91) ← 왼손이고, 91% 확신
4. 화면에 표시해볼까 ?
cv2.putText(frame, f'{label} ({score:.2f})', (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 255), 2)
f ' {label} ({ score:.2f }) ' 는 무슨 뜻인가요?
한 줄 요약 : 변수에 담긴 값을 글자로 바꾸어 멋지게 보여주는 문자열 만들기 방법이에요!
🔍 하나씩 쪼개서 볼게요
1. f ' . . . '
- 앞에 f가 붙으면 이건 f-string이라고 불러요.
- 문장 속에 변수 값을 바로 넣을 수 있는 방법이에요.
name = 'Taewoo'
print(f'Hello, {name}!') # 결과: Hello, Taewoo!
2. {label}
- 이건 "Left" 또는 "Right"라는 글자가 들어갈 자리예요.
- 즉, label이라는 변수에 저장된 문자열이 들어가는 곳이에요.
3. {score:.2f}
- 이건 숫자를 소수점 둘째 자리까지 표현해주는 방식이에요.
- 예를 들어 score가 0.97643이라면, .2f는 0.98로 만들어줘요.
- f는 float(실수형 숫자)라는 뜻이에요.
ex) 아래 내용을 출력해 보자.
label = 'Right'
score = 0.97643
text = f'{label} ({score:.2f})'
print(text)
출력 결과 --> Right (0.98)
5. 이제 아래 코드를 활용하여 실습해 보자.
import cv2
import mediapipe as mp
# 미디어 파이프의 Hand 모델을 로드합니다.
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
cap = cv2.VideoCapture(0)
with mp_hands.Hands(max_num_hands=2, min_detection_confidence=0.5, min_tracking_confidence=0.5) as hands:
while cap.isOpened():
success, frame = cap.read()
if not success:
continue
frame = cv2.cvtColor(cv2.flip(frame, 1), cv2.COLOR_BGR2RGB)
# 프레임을 미디어 파이프에 전달합니다.
results = hands.process(frame)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
# 랜드마크 좌표를 화면에 그립니다.
if results.multi_hand_landmarks and results.multi_handedness:
for hand_landmarks, handedness in zip(results.multi_hand_landmarks, results.multi_handedness):
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# 왼손/오른손 정보 가져오기
label = handedness.classification[0].label # 'Left' 또는 'Right'
score = handedness.classification[0].score
# 손목 위치에 출력
x = int(hand_landmarks.landmark[0].x * frame.shape[1])
y = int(hand_landmarks.landmark[0].y * frame.shape[0])
cv2.putText(frame, f'{label} ({score:.2f})', (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 255), 2)
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
...
728x90
반응형