원문 : https://google.github.io/mediapipe/solutions/hands
개요
손의 모양과 움직임을 인식하는 능력은 여러 기술 영역과 플랫폼에서 서비스 이용자에게 좋은 인식을 줄 수있는 중요한 요소가 될 수 있다. 예를 들어, 이 모듈은 수화 이해와 손동작 제어를 위한 프로그램의 기초를 만들 수 있으며, 증강 현실(AR) 디지털 콘텐츠의 정보를 촬영 이미지 위에 그려지게 할 수 있게 할 수도 있다. 사람들에게 자연스럽게 다가오지만, 실시간 손 인식은 손이 종종 스스로 혹은 서로 가려지고(예: 손가락/팔막 막힘 및 손 떨림) 변수도 많기 때문에 굉장히 어려운 컴퓨터 기술 작업이다.
MediaPipe Hands는 고성능 손, 손가락 추적 솔루션이다. 머신 러닝(ML)을 사용하여 각 손마마다 21개의 3D 랜드마크를 프레임마다 추론한다. 현재의 최첨단 접근 방식들은 추론을 위해 주로 강력한 하드웨어 성능에 의존하는 반면, MediaPipe의 방법은 휴대폰에서도 실시간 성능을 달성하고 2개 이상의 손을 인식할 수 도 있다. 우리는 이러한 손 인식 기능을 더 넓은 연구 개발 커뮤니티에 제공하여 새로운 응용 프로그램과 새로운 연구 방법을 자극하는 창의적인 활용 사례가 등장하기를 바란다.
ML 파이프라인(원리 이해)
MediaPipe Hands는 모든 이미지에서 작동하고 손 경계 박스를 반환하는 손바닥 감지 모델인 여러 모델로 구성된 ML 파이프라인을 활용한다. 그 후 손바닥 검출기로 추출한 편집된 이미지 영역에서 작동하고 높은 충실도를 가진 3D 핸드 키포인트를 반환하는 핸드 랜드마크 모델이다. 이 전략은 얼굴 랜드마크 모델과 함께 얼굴 감지기를 사용하는 MediaPipe Face Mesh 솔루션의 원리와 유사하다.
정확하게 잘라낸 손 이미지를 핸드 랜드마크 모델에 제공하면 데이터 확대(예: 회전, 변환 및 스케일)의 필요성을 크게 줄이고 대신 네트워크가 대부분의 용량을 좌표 예측 정확도에 할애할 수 있다. 또한, 우리의 파이프라인에서는 이전 프레임에서 식별된 손 랜드마크를 기반으로 작물을 생성할 수 있으며, 랜드마크 모델이 손의 존재를 더 이상 식별할 수 없는 경우에만 손바닥 감지가 작동하여 손의 위치를 재지정한다.
손 인식 기능의 그래프와 관련된 기능은 이곳을 참조해주세요.
모델
Palm Detection Model(손바닥 감지 모델)
초기 손 위치를 감지하기 위해 얼굴 그물망의 얼굴 감지 모델과 유사한 방식으로 모바일 실시간 사용에 최적화된 검출기 모델을 설계했다. 손 감지는 확실히 복잡한 작업이다. 우리 모델은 이미지 프레임에 비해 큰 스케일 범위(~ 20배)의 다양한 손 크기에 걸쳐 작동해야 하며 가려지는 손까지 감지할 수 있어야 한다. 얼굴은 예를 들어 눈과 입 부위와 같은 얼굴 크기에 비례하는 패턴을 가지고 있는 반면, 손의 그러한 특징이 없기 때문에 시각적 특징만으로는 손을 신뢰값을 가지고 감지하기가 상대적으로 어렵다. 대신 팔이나 몸같은 사람의 특징을 추가 맥락으로 제공하는 것이 정확한 손 위치 파악에 도움이 된다.
우리는 다른 방법을 사용하여 위의 과제를 해결한다. 먼저, 손바닥이나 주먹과 같은 중요한 물체의 경계 박스를 추정하는 것이 관절이 있는 손가락을 기준으로 손을 감지하는 것보다 훨씬 간단하기 때문에 손 감지기 대신 손바닥 감지기를 훈련시켰다. 또한 손바닥이 (손가락들 보다) 더 작은 물체이기 때문에 최대값이 아닌 억제 알고리즘은 손을 흔드는 경우나 손이 서로 겹쳐졌을 때도 잘 작동한다. 또한 손바닥은 다른 가로 세로 비율을 무시하고 정사각형 경계 상자를 사용하여 모델링할 수 있으며, 따라서 앵커(머신러닝 용어) 수를 3-5배 줄일 수 있다. 그후에는, 인코더-디코더 기능의 추출기는 작은 물체(RetinaNet 접근법과 유사)에도 더 큰 장면 상황 인식을 위해 사용된다. 마지막으로, 대규모 분산의 경우에는 많은 앵커를 돕기 위해 중점 손실을 최소화한다.
위의 기법을 사용하여 손바닥 검출에서 평균 95.7%의 정밀도를 달성하였다. 규칙적인 교차 엔트로피 손실과 디코더 없이 사용하면 평균이 86.22%밖에 되지 않는다.
Hand Landmark Model(핸드 랜드마크 모델)
전체 이미지에 대해 손바닥을 감지한 후 손 랜드마크 모델은 2차 분석을 통해 감지된 손 영역 내에서 21개의 3D 손 너클 좌표에 대한 정확한 키포인트 위치 파악을 수행한다. 즉, 직접 좌표 예측이다. 이 모델은 머신 러닝으로 학습하며 부분적으로 보이는 손이나 겹치는 손의 경우에도 인식할 수 있다.
실측 자료 데이터를 얻기 위해 아래와 같이 21개의 3D 좌표를 가진 30,000개의 실제 이미지에 수동으로 학습했다(해당 좌표당 Z 값이 존재하는 경우에는 이미지 깊이 맵에서 Z 값을 취한다). 손 포즈를 더 잘 다루고 손 기하학의 특성을 여러분이 사용하기 위해 다양한 배경에 고품질 모델을 렌더링하고 해당 3D 좌표점에 매핑한다.
솔루션 API
STATIC_IMAGE_MODE(정적_이미지_모드)
false로 설정된 경우 솔루션은 입력 이미지를 비디오 스트림으로 처리합니다. 첫 번째 입력 이미지에서 손을 감지하고 탐지가 성공하면 손 랜드마크의 위치를 추가로 파악합니다. 후속 영상에서 max_num_hands만큼의 손이 감지되고 해당 손 랜드마크가 기준이 되면 손을 추적할 수 없을 때까지 새로 기준을 잡지 않고 랜드마크만 추적한다. 따라서 대기 시간이 단축되고 비디오 프레임 처리에 이상적입니다. true로 설정하면 모든 입력 이미지에서 손 감지가 실행되므로 이미지 별로 관련 없는 이미지 일괄 처리에 이상적입니다. 기본값은 false입니다.
MAX_NUM_HANDS(손_최대_갯수)
탐지할 수 있는 최대 손 수입니다. 기본값은 2입니다.
MODEL_COMPLEXITY(모델_복잡성)
핸드 랜드마크 모델의 복잡성은 0 또는 1입니다. 랜드마크 정확도와 추론 지연 시간은 모델 복잡성과 함께 증가합니다. 기본값은 1입니다.
MIN_DETECTION_CONFIDENCE(최소_탐지_신뢰도)
탐지가 성공한 것으로 간주되는 손 감지 모델의 최소 신뢰 값([0.0, 1.0]). 기본값은 0.5입니다.
MIN_TRACKING_CONFIDENCE(최소_추척_신뢰도)
손 랜드마크 추적 모델의 최소 신뢰 값([0.0, 1.0])이 성공적으로 추적된 것으로 간주됩니다 만약 그렇지 않다면 다음 입력 영상에서 기준 손 탐지가 자동으로 호출됩니다. 이 솔루션을 높은 값으로 설정하면 지연 시간이 길어지는 대신 솔루션의 정확성을 높일 수 있습니다. static_image_mode가 True라면 무시됩니다. 여기서 손 감지는 모든 이미지에 대해 실행됩니다. 기본값은 0.5입니다.
Output(출력)
MULTI_HAND_LANDMARKS(멀티_ 손_랜드마크)
감지/추적된 손의 집합입니다. 여기서 각 손은 21개의 손 랜드마크 리스트로 표현되고 각 랜드마크는 이미지 폭과 높이로 각각 [0.0, 1.0]으로 정규화됩니다. z는 손목의 깊이를 원점으로 삼고 값이 작을수록 랜드마크 깊이를 나타냅니다. z의 크기는 x와 거의 동일한 척도를 사용합니다.
MULTI_HANDEDNESS(멀티_손잡이)
감지/추적된 손의 손잡이(왼손잡이, 오른손잡이)수집, 각 손은 레이블과 score으로 구성됩니다. 레이블은 "왼쪽" 또는 "오른쪽" 값의 문자열입니다. score은 예측된 손의 예상 확률이며 항상 0.5 이상입니다(반대 손의 예상 확률은 1 - 점수임).
입력 이미지가 좌우 반전된 경우 뒤집힌 카메라로 촬영된 경우 손이 결정된다는 점에 유의하십시오. 이를 원치 않은 경우 응용 프로그램에서 handedness 출력을 바꾸십시오.
import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
# 이미지 파일의 경우을 사용하세요.:
IMAGE_FILES = []
with mp_hands.Hands(
static_image_mode=True,
max_num_hands=2,
min_detection_confidence=0.5) as hands:
for idx, file in enumerate(IMAGE_FILES):
# 이미지를 읽어 들이고, 보기 편하게 이미지를 좌우 반전합니다.
image = cv2.flip(cv2.imread(file), 1)
# 작업 전에 BGR 이미지를 RGB로 변환합니다.
results = hands.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
# 손으로 프린트하고 이미지에 손 랜드마크를 그립니다.
print('Handedness:', results.multi_handedness)
if not results.multi_hand_landmarks:
continue
image_height, image_width, _ = image.shape
annotated_image = image.copy()
for hand_landmarks in results.multi_hand_landmarks:
print('hand_landmarks:', hand_landmarks)
print(
f'Index finger tip coordinates: (',
f'{hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].x * image_width}, '
f'{hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].y * image_height})'
)
mp_drawing.draw_landmarks(
annotated_image,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
mp_drawing_styles.get_default_hand_landmarks_style(),
mp_drawing_styles.get_default_hand_connections_style())
cv2.imwrite(
'/tmp/annotated_image' + str(idx) + '.png', cv2.flip(annotated_image, 1))
# 웹캠, 영상 파일의 경우 이것을 사용하세요.:
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("카메라를 찾을 수 없습니다.")
# 동영상을 불러올 경우는 'continue' 대신 'break'를 사용합니다.
continue
# 필요에 따라 성능 향상을 위해 이미지 작성을 불가능함으로 기본 설정합니다.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = hands.process(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())
#보기 편하게 이미지를 좌우 반전합니다.
cv2.imshow('MediaPipe Hands', cv2.flip(image, 1))
if cv2.waitKey(5) & 0xFF == 27:
break
cap.release()
'Python' 카테고리의 다른 글
[파이썬] OSError: [WinError 123] 파일 이름, 디렉터리 이름 또는 볼륨 레이블 구문이 잘못되었습니다 (0) | 2021.11.12 |
---|---|
[파이썬] MediaPipe 객체 인식(objectron) (0) | 2021.11.08 |
[파이썬] 유튜브 영상 mp3 추출 다운로드 (1) | 2021.11.04 |
[파이썬] MediaPipe 얼굴 그물망(Face Mesh) (0) | 2021.11.03 |
[파이썬] MediaPipe 얼굴 인식(Face Detection) (0) | 2021.11.02 |
글 내용 중 잘못되거나 이해되지 않는 부분은 댓글을 달아주세요! 감사합니다! 문의: puleugo@gmail.com