본문 바로가기
파이썬

파이썬 mediapipe 패키지 사용법

by ㈜㎹Ω∞ 2022. 8. 5.
728x90

mediapipe는 손가락을 인식하는 패키지입니다. 손가락 마디마다 번호가 있어서 번호를 이용해서 프로그래밍합니다. https://google.github.io/mediapipe/solutions/hands.html에서 자세히 확인 가능합니다. mediapipe를 사용하기 위해서는 pip install mediapipe를 해서 mediapipe를 설치합니다.

 

mediapipe

 

  • landmark[번호] : 손가락 마다마다 지정된 번호가 있는데 [번호]에 마디 번호를 입력해서 사용합니다.
  • mp.solutions.drawing_utils : 점으로 손가락 마디를 표시합니다.
  • mp.solutions.hands : 연두색으로 손가락 마디를 표시합니다.
  • mp_hands.Hands : 손가락을 인식하는 모듈을 초기화합니다.
  • max_num_hands : 인식하려는 손 수를 정합니다.(1이면 1개, 2면 2개)
  • min_detection_confidence와 min_tracking_confidence : 옵션입니다.

 

캠에 손가락 인식하는 코드

 

import cv2 as cv
import mediapipe as mp

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

capture = cv.VideoCapture(0)

with mp_hands.Hands(	# 손가락인식 초기화
    max_num_hands=1,	# 인식할려는 손의 수
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
    ) as hands:	# hands라고 정의합니다.

    while capture.isOpened():
        ret, frame = capture.read()
        if not ret:
            continue
        frame = cv.cvtColor(cv.flip(frame, 1), cv.COLOR_BGR2RGB)
        results = hands.process(frame)

        frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)
        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                finger1 = hand_landmarks.landmark[8]	# 두번째 손가락사용
                ### !!추가!! ###
                # 뼈마디를 그립니다.
                mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
        cv.imshow("Finger", frame)	# 뼈마디를 보여줍니다.
        if cv.waitKey(1) == 27:
            break
        
capture.release()
cv.destroyAllWindows()

 

### !!추가!! ### 부분에 밑에 코드를 추가하면 영상에 좌표가 표시됩니다.

 

        finger1 = hand_landmarks.landmark[8]
        finger1_x = float("{0:0.3f}".format(finger1.x))
        finger1_y = float("{0:0.3f}".format(finger1.y))
        coordinate = "x:{0}, y:{1}".format(finger1_x, finger1_y)
        cv.putText(frame, coordinate, (30, 30), font, 1, (255,0,0))

 

  • finger1_x = float("{0:0.3f}".format(finger1.x)) : finger1의 x좌표를 나타냅니다.
  • finger1_y = float("{0:0.3f}".format(finger1.y)) :  finger1의 y좌표를 나타냅니다.

 

엄지와 검지의 거리를 나타내는 코드

 

 

if results.multi_hand_landmarks:
    for hand_landmarks in results.multi_hand_landmarks:
        finger1 = hand_landmarks.landmark[4]
        finger2 = hand_landmarks.landmark[8]
        diff = abs(finger1.x - finger2.x)
        diff = int(diff*100)                
        diff_text = "difference:{0}".format(diff)
        cv.putText(frame, diff_text, (30, 30), font, 1, (255,0,0))

 

  • 절댓값을 이용해서 계산합니다.
  • finger1 : 엄지입니다.
  • finger2 : 검지입니다.
  • x값이 아닌 y값을 구하고 싶다면 diff = abs(finger1.x - finger2.x)을 diff = abs(finger1.y - finger2.y)라고 변경하면 됩니다.
  • x : 양옆 거리(가로)
  • y : 위아래 거리(세로)

 

전체 코드

 

import cv2 as cv
import mediapipe as mp

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

capture = cv.VideoCapture(0)

font = cv.FONT_HERSHEY_DUPLEX

with mp_hands.Hands(
    max_num_hands=1,
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
    ) as hands:

    while capture.isOpened():
        ret, frame = capture.read()
        if not ret:
            continue
        frame = cv.cvtColor(cv.flip(frame, 1), cv.COLOR_BGR2RGB)
        results = hands.process(frame)

        frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)
        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                finger1 = hand_landmarks.landmark[4]
                finger2 = hand_landmarks.landmark[8]
                diff = abs(finger1.x - finger2.x)
                diff = int(diff*100)                
                diff_text = "difference:{0}".format(diff)
                cv.putText(frame, diff_text, (30, 30), font, 1, (255,0,0))
                mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
        cv.imshow("Finger", frame)
        if cv.waitKey(1) == 27:
            break
        
capture.release()
cv.destroyAllWindows()
728x90

댓글