반응형
원본 코드 : https://google.github.io/mediapipe/solutions/hands.html
1. 패키지 설치 하기
pip install mediapipe
2. 라이브러리 임포트
import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
3. 카메라에서 손을 인식하여 분석하기
옵션
- static_image_mode(정적이미지모드):false인 경우 입력이미지를 비디오 스트림으로 처리한다. 첫번째 입력 이미지에서 손을 감지하고 탐지가 성공하면 손랜드마크의 위치를 추가로 파악한다.후속영상에서 max_num_hands만큼의 손이 감지되고 해당 손 랜드마크가 기준이 되면 손을 추적할 수 없을 때 까지 새로 기준을 잡지 않고 랜드마크만 추적한다. 따라서 대기시간이 단축되고 비디오 프레임 처리에 이상적이다. true 인 경우 모든 입력 이미지에서 손감지가 실행되므로 일괄 처리에 이상적이다. 기본값은 false
- max_num_hands : 손 최대 갯수(기본값은 2)
- model_complexity(모델 복잡성) : 0또는 1이며 랜드마크 정확도와 추론 지연시간은 모델 복잡성과 함께 증가한다.(기본값은 1)
- min_detection_confidence(최소 탐지 신뢰도):탐지가 성공한 것으로 간주되는 손감지 모델의 최소 신뢰값, 기본값은 0.5
- min_tracking_confidence(최소 추적 신뢰도):손랜드마크 추적 모델의 최소 신뢰값(0~1) 이 성공적으로 추적된 것으로 간주된다. 만약 그렇지 않다면 다음 입력 영상에서 기준 손 탐지가 자동으로 호출된다. 이 솔루션을 높은 값으로 설정하면 지연 시간이 길어지는 대신 솔루션의 정확성을 높일 수 있다. static_imae_mode 가 true라면 무시된다. 기본값은 0.5
cap = cv2.VideoCapture(0)
with mp_hands.Hands(
model_complexity=0,
min_detection_confidence=0.5,
min_tracking_confidence=0.5) as hands:
while cap.isOpened():
success, image = cap.read()
if not success:
print("Ignoring empty camera frame.")
# If loading a video, use 'break' instead of 'continue'.
continue
# To improve performance, optionally mark the image as not writeable to
# pass by reference.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = hands.process(image)
# Draw the hand annotations on the image.
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(
image,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
mp_drawing_styles.get_default_hand_landmarks_style(),
mp_drawing_styles.get_default_hand_connections_style())
# Flip the image horizontally for a selfie-view display.
cv2.imshow('MediaPipe Hands', cv2.flip(image, 1))
if cv2.waitKey(5) & 0xFF == 27:
break
cap.release()
이렇게 인식하는 모델을 다음과 같이 활용해 볼 수 있겠네요.
엄지와 검지 사이의 거리를 측정하여 볼륨 조절기를 만든다든 가 할때 엄지는 4번 인덱스 검지는 8번 인덱스이니까.
그 거리 측정 하는 코드를 활용하여
thumb = hand_landmarks.landmark[4]
index = hand_landmarks.landmark[8]
diff = abs(index.x - thumb.x)
화면에 출력해 보면
cv2.putText(
image, text='Diff: %d' % (int(diff*1000)), org=(10, 30),
fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
color=255, thickness=2)
실행 결과
전체 코드
import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
cap = cv2.VideoCapture(0)
# fourcc 값 받아오기, *는 문자를 풀어쓰는 방식, *'DIVX' == 'D', 'I', 'V', 'X'
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
# 정수 형태로 변환하기 위해 round
w = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS) # 카메라에 따라 값이 정상적, 비정상적
# 웹캠으로 찰영한 영상을 저장하기
# cv2.VideoWriter 객체 생성, 기존에 받아온 속성값 입력
out = cv2.VideoWriter('output.avi', fourcc, fps, (w, h))
with mp_hands.Hands(
model_complexity=0,
min_detection_confidence=0.5,
min_tracking_confidence=0.5) as hands:
while cap.isOpened():
success, image = cap.read()
if not success:
print("Ignoring empty camera frame.")
# If loading a video, use 'break' instead of 'continue'.
continue
#out.write(image)
# To improve performance, optionally mark the image as not writeable to
# pass by reference.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = hands.process(image)
# Draw the hand annotations on the image.
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
diff = 0
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
thumb = hand_landmarks.landmark[4]
index = hand_landmarks.landmark[8]
diff = abs(index.x - thumb.x)
print(diff)
mp_drawing.draw_landmarks(
image,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
mp_drawing_styles.get_default_hand_landmarks_style(),
mp_drawing_styles.get_default_hand_connections_style())
# Flip the image horizontally for a selfie-view display.
image = cv2.flip(image, 1)
cv2.putText(
image, text='Diff: %d' % ( int(diff * 1000)), org=(10, 30),
fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
color=255, thickness=2)
cv2.imshow('MediaPipe Hands', image)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
out.release()
반응형
'머신러닝 > 7. 머신러닝 활용하기' 카테고리의 다른 글
[머신러닝 활용] 동영상 자동편집 (0) | 2022.12.14 |
---|---|
[머신러닝 활용] 손가락을 인식하여 가위,바위,보 인식하기 (0) | 2022.12.14 |
[머신러닝활용]cv2.pencilSketch 를 이용하여 동영상을 스케치형태로 만들자 (0) | 2022.12.07 |
[머신러닝활용] Yolov4를 활용한 차량 번호판 인식 (0) | 2022.12.07 |
[머신러닝 활용] PySceneDetect 를 사용해서 동영상 분석 (0) | 2022.12.05 |