AI Project(1) ≡ Mediapipe Hand

Acrylic·2024년 4월 19일

프로젝트 계획

대충 애플 뭐시깽이에서 나오는 것마냥 손을 어떻게 하면 폭죽 터지고 그런 거 만들겠다는데 그러려면 일단 Mediapipe에 있는 손을 인식하면 해결될 일이다.

그런데 아직 사용 방법을 모르기에 일단 배우기로 했다.

PyCharm 환경

파이썬 실험 작업하기에 적절한 PyCharm을 사용하기로 했다.

줄 네 개 누르고 FileSettings, Project:(프로젝트 이름)에 들어가면 Python Interpreter라고 있을 건데 들어가서 + 누르고 mediapipe를 검색하면 뜨니까 설치해 준다.

Mediapipe 손 인식

https://makernambo.com/154

이런 블로그가 있길래 들어가 봤는데 정리가 잘 돼 있었다. 마침 또 예제를 손 인식으로 해서 코드를 바로 찾을 수 있었다.

import cv2
import mediapipe as mp
 
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
 
cap = cv2.VideoCapture(0)
 
with mp_hands.Hands(
    max_num_hands=1,
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5) as hands:
 
    while cap.isOpened():
        success, image = cap.read()
        if not success:
            continue
        image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
 
        results = hands.process(image)
 
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
 
        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                finger1 = int(hand_landmarks.landmark[4].x * 100 )
                finger2 = int(hand_landmarks.landmark[8].x * 100 )
                dist = abs(finger1 - finger2)
                cv2.putText(
                    image, text='f1=%d f2=%d dist=%d ' % (finger1,finger2,dist), org=(10, 30),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
                    color=255, thickness=3)
 
                mp_drawing.draw_landmarks(
                    image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
 
        cv2.imshow('image', image)
        if cv2.waitKey(1) == ord('q'):
            break
 
cap.release()

finger1을 보면 int(hand_landmarks.landmark[4].x * 100 ) 이렇게 돼 있는데
4는 그냥 여기 아래에 있는 거라 보면 된다.

그러면 엄지손가락 끝부분을 나타내는 코드라 보면 되겠다.
이걸 이용해서 뭔 코드를 가동시키든 하겠지.

엄지 접는 거 인식

실험으로 엄지손가락을 접었을 때 뭔가가 작동되었으면 하는데 dist가 마침 그걸 해결해 주는 듯했다. 코드를 보면 f1f2 사이의 거리를 나타내고 있었다.
그렇다면 대충 중간 손가락 초반 부분이랑 가까울 때 실행하면 되지 않을까 해서 해 보았다.

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands

cap = cv2.VideoCapture(0)

with mp_hands.Hands(
        max_num_hands=1,
        min_detection_confidence=0.5,
        min_tracking_confidence=0.5) as hands:
    while cap.isOpened():
        success, image = cap.read()
        if not success:
            continue
        image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)

        results = hands.process(image)

        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                finger1 = int(hand_landmarks.landmark[4].x * 100)
                finger2 = int(hand_landmarks.landmark[9].x * 100)
                dist = abs(finger1 - finger2)
                cv2.putText(
                    image, text='f1=%d f2=%d dist=%d ' % (finger1, finger2, dist), org=(10, 30),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
                    color=255, thickness=3)

                mp_drawing.draw_landmarks(
                    image, hand_landmarks, mp_hands.HAND_CONNECTIONS)

                if dist <= 2:
                    print("안녕")

        cv2.imshow('image', image)
        if cv2.waitKey(1) == ord('q'):
            break

cap.release()

이렇게 하면 아무것도 안 되겠지만

이렇게 하면 안녕이 도배돼서 나온다.
근데 엄지를 꼭 저렇게 접으라는 법은 없다. 좀 아래쪽에서 접을 수도 있는데 아무튼 어떻게 하는지는 대충 알았다.

그러면 저 가운뎃손가락만 올려 놓았을 때 인식한다면 저번에 있던 코드를 만들 수 있다는 거다(전이 학습이냐 아니냐의 차이는 존재하지만).

profile
프런트엔드 개발자 지망생

0개의 댓글