카메라로 손과 얼굴을 읽는 AI를
오늘 내 컴퓨터에서 직접 돌려 봅니다
MediaPipe는 구글이 미리 학습시켜 둔 "보는 능력"을 빌려 쓰는 도구 상자입니다.
수많은 사진으로 공부를 끝낸 프로그램 부품. "손 사진을 주면 관절 위치를 답하는 문제집 만점자"라고 생각하면 됩니다.
이번 수업에서는 비전(시각) 기능 가운데 대표적인 두 가지를 직접 다룹니다.
손 하나에서 관절 위치 21개 점을 실시간으로 찾아냅니다. 손가락 개수 세기, 제스처 인식의 재료가 됩니다.
얼굴에서 478개 점을 찾습니다. 눈동자(홍채) 위치와, 표정을 숫자로 알려주는 표정 수치 52가지도 함께 나옵니다.
주먹, 브이(V), 엄지척 같은 대표 손 모양 7가지를 이름으로 알려줍니다. 플레이그라운드에서 사용합니다.
랜드마크(landmark)는 몸의 중요한 위치마다 찍히는, 번호가 정해진 점입니다.
landmarks[8] 한 줄이 됩니다.동영상을 이루는 낱장 사진 한 장. 웹캠은 보통 1초에 30장 정도의 프레임을 보내 줍니다.
랜드마크의 좌표는 픽셀이 아니라 0에서 1 사이의 비율값으로 옵니다.
MediaPipe의 최신 사용법(Tasks API)은 전자레인지를 쓰는 순서와 같습니다.
options = HandLandmarkerOptions( # ② 옵션 설정
base_options=BaseOptions(model_asset_path="hand_landmarker.task"), # ① 모델 파일
running_mode=RunningMode.VIDEO,
)
landmarker = HandLandmarker.create_from_options(options)
result = landmarker.detect_for_video(frame, timestamp) # ③ detect 호출
학습이 끝난 모델을 담은 상자 파일. 우리 예제는 첫 실행 때 인터넷에서 자동으로 내려받습니다.
같은 모델도 입력이 무엇이냐에 따라 세 가지 모드 중 하나로 돌립니다.
| 모드 | 입력 | 특징 |
|---|---|---|
| IMAGE | 사진 1장 | 가장 단순. 순서 개념이 없음 |
| VIDEO | 동영상·웹캠 프레임을 순서대로 | 앞 프레임 정보를 활용해 더 안정적. 이번 수업에서 사용 |
| LIVE_STREAM | 실시간 영상 (비동기) | 결과가 나중에 별도 함수로 도착. 빠르지만 코드 흐름이 어려움 |
설치는 처음 한 번만 하면 됩니다. 필요한 것은 네 가지입니다.
아래 파일 하나를 내려받아 실행하면 파이썬 3.12와 MediaPipe를 한 번에 설치할 수 있습니다.
python.org에서 설치할 때, 첫 화면의 체크박스 하나가 가장 중요합니다.
이미 파이썬이 설치되어 있다면 이 슬라이드는 건너뛰어도 됩니다.
필요한 꾸러미(패키지) 두 개를 한 줄로 설치합니다.
설치가 잘 되었는지 한 줄로 확인합니다. 검은 창은 이걸로 끝입니다.
이제부터 코드는 IDLE에서 실행합니다. 검은 창은 더 이상 필요 없습니다.
파이썬을 설치하면 따라오는 기본 코드 편집기. 쓰던 편집기(VS Code 등)가 있다면 그대로 써도 됩니다.
웹캠 속 내 손 위에 21개의 점과 뼈대 선이 실시간으로 그려지고, 화면에 편 손가락 개수가 표시되는 프로그램을 만듭니다.
21개 점의 번호는 손목(0)에서 시작해 손가락 끝으로 갈수록 커집니다.
| 번호 | 위치 |
|---|---|
| 0 | 손목 |
| 4 | 엄지 끝 |
| 8 | 검지 끝 |
| 12 | 중지 끝 |
| 16 | 약지 끝 |
| 20 | 새끼 끝 |
아래 코드를 통째로 복사해 IDLE 새 파일에 붙여넣고 F5를 누르세요.
코드를 불러오는 중...
코드 맨 위의 설정값 블록은 프로그램의 손잡이입니다. 몸통을 몰라도 손잡이만 돌리면 동작이 바뀝니다.
NUM_HANDS = 1 # [수정 지점] 인식할 손 개수 (1 또는 2)
DOT_COLOR = (0, 255, 0) # [수정 지점] 점 색깔 (파랑, 초록, 빨강) 각 0~255
def download_model():
"""모델 파일이 없으면 인터넷에서 한 번만 받아 옵니다."""
if os.path.exists(MODEL_FILE):
return
urllib.request.urlretrieve(MODEL_URL, MODEL_FILE)
while 반복문 안에서는 매 프레임 같은 다섯 동작이 되풀이됩니다.
1초에 처리하는 장면 수. 15 이상이면 실시간으로 부드럽게 느껴집니다.
count_fingers()는 복잡한 AI가 아니라, 좌표를 비교하는 단순한 규칙입니다.
| 수정 지점 | 효과 |
|---|---|
| DOT_COLOR / DOT_SIZE | 점의 색과 크기 |
| NUM_HANDS = 2 | 두 손 동시 인식 |
| count_fingers()의 규칙 | 나만의 판정 규칙 |
| print(...) 주석 해제 | 검지 끝 좌표를 숫자로 관찰 |
직접 바꿔 봅시다. 저장(Ctrl+S) 후 다시 F5를 누르면 바뀐 코드로 실행됩니다.
DOT_COLOR = (0, 0, 255)
색 순서가 (파랑, 초록, 빨강)이라는 점을 기억하세요.
NUM_HANDS = 2
두 손을 화면에 올리면 각 손의 손가락 개수가 따로 표시됩니다.
[수정 지점] 주석이 달린 print(...) 줄의 #을 지우고 손의 움직임에 따라 숫자가 어떻게 변하는지 관찰해 보세요.
얼굴 위 478개의 점, 눈동자(홍채) 강조 표시, 표정 수치 게이지, 그리고 시선 방향까지 한 화면에 띄웁니다.
블렌드셰이프(blendshape)는 표정 하나하나를 0~1 사이 게이지로 알려주는 52개의 계기판입니다.
얼굴 478개 점의 마지막 10개(468~477)는 눈동자, 곧 홍채의 점입니다.
눈동자의 색이 있는 부분. 홍채의 중심을 따라가면 곧 시선을 따라가는 것과 같습니다.
손 예제와 같은 방법입니다. 통째로 복사해 IDLE 새 파일에 붙여넣고 F5를 누르세요.
코드를 불러오는 중...
뼈대는 같으므로, 아래 네 군데만 짚으면 코드 전체를 이해한 것입니다.
| 어디 | 무엇이 달라졌나 |
|---|---|
| 모델 파일 | hand_landmarker.task → face_landmarker.task |
| 옵션 | output_face_blendshapes=True — 표정 계기판 52개를 함께 계산해 달라는 요청 |
| 그리기 | 478개 점은 작게, 홍채 10개는 크고 붉게 구분해서 그림 (draw_face) |
| 새 함수 | gaze_x() 시선 계산, draw_blendshape_bars() 게이지 막대 |
표정과 시선을 조건문의 재료로 써 봅시다.
eyeBlinkLeft가 0.5를 넘는 순간을 세어 보세요. 힌트: "이전 프레임에는 안 넘었는데 지금 넘었다"를 변수 하나로 기억하면 됩니다.
Gaze가 LEFT면 "<<<", RIGHT면 ">>>"를 화면 가운데에 표시해 보세요. gaze_x() 값과 cv2.putText를 조합합니다.
WATCH_BLENDSHAPES에 "browInnerUp"을 추가하고, 눈썹을 올릴 때 게이지가 차오르는 것을 확인하세요.
오늘 다룬 두 예제는 그대로 수행 과제의 출발점입니다. 각 아이디어 옆에 고칠 곳을 적어 두었습니다.
편 손가락 0개=바위, 2개=가위, 5개=보. count_fingers()의 결과로 조건문을 만들면 됩니다.
한쪽 eyeBlink만 높고 반대쪽은 낮을 때 동작. WATCH_BLENDSHAPES와 조건문 조합.
NUM_HANDS=2로 두고 두 손의 손가락 개수를 더해서 표시. 두 손 덧셈 연습기가 됩니다.
gaze_x() 값으로 화면 속 네모를 좌우로 움직여 보세요. 시선 마우스의 원리입니다.
오류는 실패가 아니라 단서입니다. 증상을 찾아 그대로 따라 해 보세요.
| 증상 | 원인 | 해결 |
|---|---|---|
| 카메라가 안 켜짐 | 다른 앱이 카메라 사용 중, 또는 권한 꺼짐 | Zoom·Teams 등 종료 → 윈도우 설정 → 개인 정보 → 카메라 허용. 그래도 안 되면 CAM_INDEX를 1로 |
| 'pip'은(는) 인식할 수 없는 명령… | 설치 때 PATH 체크를 안 함 | 파이썬 설치 파일을 다시 실행 → "Add python.exe to PATH" 체크 후 재설치 |
| 모델 다운로드 실패 | 인터넷·학교 방화벽 | 인터넷 연결 확인 후 재실행. 안 되면 선생님이 내려받은 .task 파일을 코드와 같은 폴더에 복사 |
| 화면이 뚝뚝 끊김 | PC 성능·역광 | 다른 프로그램 닫기, 조명을 얼굴 앞쪽으로. FPS 표시로 개선을 확인 |
| 창이 안 닫힘 | 종료 키를 모름 | 카메라 창을 클릭한 뒤 ESC. 멈춘 것 같으면 IDLE 메뉴 Shell → Restart Shell |
다음 시간에는 오늘 배운 랜드마크 값을 브라우저에서 노드로 연결해, 얼굴과 손으로 ESP32 보드를 조종합니다.
이 세 가지만 기억하면 MediaPipe의 어떤 기능이든 같은 방법으로 쓸 수 있습니다.