MediaPipe Face Landmarker — 학부생을 위한 학습 교재

02. 전체 동작 파이프라인 — RGB 한 장이 478점·52계수·4×4 행렬이 되기까지

목차

RGB 이미지 한 장이 들어가서 478개 점, 52개 표정 계수, 4×4 행렬이 나오기까지 단계마다 무슨 일이 벌어지는지 끊김 없이 따라간다.

00장에서 정의한 용어(검출, ROI, 메시, 회귀, 정규화 좌표, canonical model, 블렌드셰이프, 변환 행렬)를 그대로 쓴다.

2.1 큰 그림을 먼저 — end-to-end 한 장

01장에서 Face Landmarker가 세 모델의 합본임을 봤다. 그 합본이 이미지 한 장을 어떻게 처리하는지 한눈에 본다. 본문 단계 번호 (a)~(g)가 아래 다이어그램 노드와 1:1로 대응한다.

subset 146 x 2D

if output_face_blendshapes

align to canonical mesh

if output_facial_transformation_matrixes

no

yes

(a) RGB image / frame

(a) preprocess: to RGB, resize for detector

(b) BlazeFace short-range 192x192
detect bbox + 6 keypoints

(c) ROI crop and align
rotate so eyes are horizontal, 256x256 patch

(d) Face Mesh V2 256x256
regress 478 landmarks (ROI-normalized)

(g) de-normalize: ROI space to original image space

output: face_landmarks 478 (x,y,z)

(e) Blendshape V2 1x146x2
regress 52 coeffs

output: face_blendshapes 52

(f) 4x4 facial transformation matrix

output: transform matrix 4x4

face presence flag
>= min_face_presence_confidence?

drop / re-run detector next time

위 그림을 세 가지로 읽으면 된다.

  • 실선 주경로 (a)→(b)→(c)→(d)→(g)→출력은 항상 실행된다. 최종 산출은 478 랜드마크다.
  • 점선 곁가지 둘(블렌드셰이프, 변환 행렬)은 옵션을 켰을 때만 실행된다. 기본은 꺼짐이다.
  • (b) 검출 단계는 IMAGE 모드에서는 매 프레임 돈다. VIDEO/LIVE_STREAM 추적 모드에서는 건너뛴다(2.4절).

단계별로 무엇을 입력받아 무엇을 내놓는가

단계 무엇을 하나 입력 출력 좌표 공간
(a) 전처리 RGB 변환·검출기용 리사이즈 원본 RGB 이미지/프레임 검출기 입력 텐서(192×192) 원본 픽셀
(b) 얼굴 검출 얼굴 위치 거칠게 찾기 192×192 이미지 bbox + 6 키포인트 + 점수 원본 이미지 정규화
(c) ROI crop·align 얼굴 잘라 회전·정규화 bbox·키포인트 + 원본 256×256 정렬된 패치 + ROI 변환정보 원본 → ROI 정규화
(d) 랜드마크 회귀 478점 얹기 256×256 패치 478×(x,y,z) + presence flag ROI 정규화
(e) blendshape(옵션) 표정 계수 회귀 146점 서브셋(2D) 52 계수 [0,1] (좌표 아님)
(f) 변환행렬(옵션) 머리 자세 행렬 478점 + canonical 메시 4×4 행렬 metric(cm) ↔ canonical
(g) 후처리·역정규화 ROI→원본 좌표 환산, smoothing (d) 출력 + ROI 변환정보 원본 정규화 478점 + 결과 객체 ROI → 원본 정규화

맨 오른쪽 "좌표 공간" 열을 눈여겨보자. (d)에서 메시 모델은 ROI 패치 기준으로 478점을 내놓고, (g)에서 그것을 원본 이미지 기준 0~1 정규화로 되돌린다. 사용자가 보는 최종 좌표는 항상 원본 기준이다. 좌표가 공간을 어떻게 오가는지는 2.5절에서 따로 정리한다.

광고 · Advertisements

2.2 단계별 상세 — 무슨 일이 벌어지는가

(a) 입력 이미지(RGB) 전처리

Face Landmarker는 RGB 이미지를 받는다. 사용자가 원본 해상도를 직접 맞출 필요는 없다. 내부에서 단계마다 알아서 리사이즈한다. 검출 단계로 넘기기 전, 입력은 검출기 모델 입력 크기인 192×192로 줄인다.

검출기 입력 해상도 주의. MediaPipe의 독립 Face Detector 가이드는 BlazeFace short-range 입력을 128×128로 적는다. 반면 Face Landmarker 번들 문서는 검출기 입력을 192×192로 적는다. 이 책은 번들 기준 192×192를 따른다(06장에서 확정). 두 표기는 같은 BlazeFace 계열의 배포 변형 차이로 보이며, 거친 검출용 소해상도 입력이라는 본질은 같다.

입력 품질에는 한계가 있다. Face Landmarker는 셀피 전면 카메라에 맞춰져 있다. 다음 경우엔 잘 동작하지 않는다.

  • 시선 회피가 80°를 넘을 때
  • 좌우 기울임(roll)이 8°를 넘을 때
  • 얼굴이 50% 미만만 보일 때
  • 너무 멀어 192×192로 키울 수 없을 만큼 작은 얼굴

반대로 위치·스케일 10% 시프트와 8° roll까지는 견딘다. 더 자세한 입력 요구사항은 06장에서 다룬다.

(b) 얼굴 검출 — BlazeFace short-range

무엇을 하나. 큰 화면 전체에서 얼굴이 있는지, 있다면 어디인지를 거칠게 찾는다. 출력은 세 가지다.

  1. 바운딩 박스(bbox): 얼굴을 감싸는 사각형. 원본 이미지에 정규화된 좌표다.
  2. 6개 얼굴 키포인트: 공식 표기로 left eye, right eye, nose tip, mouth, left eye tragion, right eye tragion이다. 양 눈, 코끝, 입, 그리고 양 귀의 tragion(귀 앞 연골 돌기)이다. 이 6점이 다음 단계(ROI 정렬)에서 회전·스케일 기준이 된다.
  3. 검출 신뢰도 점수: min_face_detection_confidence(기본 0.5) 이상이어야 "검출 성공"으로 인정한다. 공식 정의는 "The minimum confidence score for the face detection to be considered successful"이다.

왜 검출기를 따로 두나. 화면 어디에 얼마나 큰 얼굴이 있는지 모르는 상태에서 478점을 한 번에 정밀 회귀하기는 어렵다. 그래서 단계를 나눈다. 가벼운 검출기가 "여기 얼굴 있음, 대략 이 박스와 각도"를 먼저 잡는다. 무거운 정밀 작업은 잘 정리된 패치에만 적용한다.

검출기는 작고 빠르다. BlazeFace는 모바일 GPU에서 1ms 안팎을 노린 경량 single-shot 검출기다. 검출기 단독으로 약 0.23 MB, Pixel 6 CPU에서 2.94 ms다(06장). 큰 화면을 훑는 일은 이 작은 모델이 전담한다.

검출기는 정렬에 쓸 재료도 준다. bbox만으로는 얼굴이 기울었는지 알 수 없다. 6 키포인트, 특히 양 눈이 있어야 회전 각도를 계산해 얼굴을 똑바로 세울 수 있다. 이것이 (c)에서 결정적이다.

이 설계는 BlazeFace 논문 그대로다. BlazeFace는 2D 회전 bounding rectangle과 핵심 anchor 점을 내도록 만들어져, "정확한 얼굴 ROI를 입력으로 요구하는 task-specific 모델"에 곧바로 이어진다. 검출이 다음 단계에 ROI를 넘기는 1단계라는 01장의 설계 의도와 같다.

(c) ROI 추출·정렬 (crop & align) — 파이프라인의 연결 고리

무엇을 하나. (b)의 bbox·키포인트를 받아, 원본 이미지에서 얼굴 영역을 잘라(crop) 내고 회전·스케일을 정규화(align)해 메시 모델 입력 256×256을 만든다. 얼굴 메시 모델 카드 기준으로는 25% 마진을 둔 크롭을 256×256으로 리사이즈한다.

어떻게 정렬하나. 정렬은 세 가지를 한다.

  • 회전 보정: 두 눈 키포인트를 잇는 선이 수평이 되도록 패치를 회전시킨다. 머리가 기울어 들어와도 메시 모델은 두 눈이 가로로 놓인, 똑바로 선 얼굴을 본다.
  • 스케일·위치 정규화: bbox와 키포인트로 얼굴 크기·중심을 정해 256×256 안에 일정하게 채운다.
  • 변환정보 보관: 이때 적용한 회전각·스케일·평행이동을 ROI 변환으로 따로 저장한다. (d)가 ROI 패치 기준으로 좌표를 내면, (g)에서 이 변환을 역으로 적용해 원본 좌표로 되돌려야 하기 때문이다(2.5절).

왜 중요한가. 메시 모델이 항상 비슷한 포즈·스케일의 입력을 받는다. 그래서 회전·스케일·이동 변형을 데이터 증강으로 외우지 않아도 정확히 동작한다. MediaPipe 설명 그대로 "정확히 크롭된 얼굴 ROI를 받기에 스케일·회전·이동된 얼굴을 증강 없이 정밀 처리할 수 있다." 모델 용량을 변형 흡수에 쓰지 않고 정밀도에 집중시키는 것이 이 정렬의 핵심 이득이다.

bbox + 6 keypoints (original image)

compute roll angle from two eyes

rotate so eyes are horizontal

crop with ~25% margin

normalize to 256x256 patch

save ROI transform (rotation, scale, translation)

aligned 256x256 face patch to mesh model

ROI 정렬은 여권 사진 자동 보정과 비슷하다. 사람마다 다르게 기울고 멀리 찍힌 얼굴을 "가운데·정면·일정 크기"로 맞춰 준다. 그러면 다음 검사관인 메시 모델은 늘 같은 규격의 사진만 보면 되니 실수가 준다. 그리고 원래 사진을 얼마나 돌리고 잘랐는지 메모해 둔다. 나중에 점을 원래 사진 위로 되돌리기 위해서다.

(d) 랜드마크 회귀 — Face Mesh V2

무엇을 하나. 정렬된 256×256 얼굴 패치를 받아 478개 3D 랜드마크를 회귀한다. 동시에 face presence flag(얼굴 존재 확률, 기본 임계 0.5)도 낸다.

478점의 구성은 표면 메시 468점과 홍채 10점이다. 표면 메시는 canonical_face_model 정점으로 인덱스 0–467이고, 홍채는 MediaPipe Iris로 인덱스 468–477이다. 여기서는 메시 모델이 478점을 ROI 기준으로 회귀한다는 흐름만 짚는다. 상세 분해·인덱스·영역표는 03장에서 다룬다.

이 478점은 ROI 패치 기준 정규화 좌표다. 원본 이미지 기준이 아니다. 그래서 (g)에서 역정규화가 필요하다. 모델은 MobileNetV2를 닮은 커스텀 블록의 경량 CNN이다(모델 날짜 2022-09-15). 478점을 1D 텐서로 펼쳐 출력하고 face flag를 함께 낸다.

Attention Mesh의 영역 정제. 단순 회귀는 얼굴 전체를 한 해상도로 본다. 그런데 눈·입술·홍채는 표정·시선 정확도에 결정적이라 더 높은 해상도가 필요하다. 01장에서 본 Attention Mesh(arXiv:2006.10962)가 이를 푼다. 한 서브모델이 478 메시 전체를 예측해 입술·양안 ROI를 정하고, 각 영역 전용 서브모델이 그 영역만 고해상도로 정제한다(입술 약 76점, 눈 약 71점 + 홍채 5점/눈). 이 영역 주의(attention) 구조 덕에 의미 영역 정밀도를 높이면서도 단일 네트워크로 cascade 대비 약 30% 빠르게 동작한다. 레거시 Face Mesh에서 refine_landmarks=True가 켜던 동작이 바로 이 정제다. 현행 Face Landmarker는 이를 항상 적용해 기본 478점을 낸다.

aligned 256x256 patch

Face Mesh V2 (MobileNetV2-like)

full mesh 478 (coarse)

region attention: lips / left eye / right eye

refine eyes, lips, iris at higher res

478 landmarks (ROI-normalized) + presence flag

주경로의 핵심 산출인 478점이 나왔다. 이제 옵션 곁가지 둘을 본다.

(e) (옵션) blendshape — Blendshape V2

무엇을 하나. output_face_blendshapes=True일 때만 실행된다. 메시 478점 중 146점 서브셋(입술·눈·눈썹·홍채·얼굴 윤곽의 2D 좌표만)을 입력 1×146×2로 받아 52개 표정 계수([0,1])를 회귀한다.

여기서 한 가지 오해를 바로잡는다. 이것은 이미지를 다시 보지 않는 별도 2차 모델이다(경량 MLP-Mixer). 첫 모델이 만든 랜드마크 좌표만 본다. 그래서 파이프라인 그림에서 메시 모델로부터 점선으로 갈라져 나온다.

52개 계수는 _neutral(idx 0, placeholder) 하나에 표정계수 51개를 더한 것이다. ARKit과 51개는 공통이지만, MediaPipe 기본에는 tongueOut이 없다(옵션으로 켜면 53번째). 합이 1이 되어야 한다는 제약은 없는 다중 회귀다. 왜 146점만 쓰는지, MLP-Mixer 내부 구조, 학습 데이터는 04장에서 깊게 다룬다.

(f) (옵션) facial transformation matrix

무엇을 하나. output_facial_transformation_matrixes=True일 때, 얼굴마다 4×4 변환행렬을 낸다. 이 행렬은 canonical(표준) 얼굴 모델을 현재 검출된 얼굴의 위치·회전·크기로 옮기는 강체 변환이다(회전+이동+스케일). 공식 정의는 "FaceLandmarker uses the matrix to transform the face landmarks from a canonical face model to the detected face, so users can apply effects on the detected landmarks."이다.

이것은 별도 신경망이 아니다. 검출된 478 메시를 표준 메시에 정렬(fit)해 얻는 후처리 결과다. 그래서 번들에 큰 모델로 따로 잡히지 않는다. GHUM 모델이 내부적으로 6D 회전 표현으로 머리 회전을 예측해 행렬로 변환하는 경로도 있다(04장).

행렬이 담는 것은 머리 자세다. 좌상단 3×3이 회전과 스케일(yaw/pitch/roll), 오른쪽 열이 이동(tx, ty, tz), 마지막 행이 (0 0 0 1)이다. 표정을 담는 블렌드셰이프와는 역할이 다르다(블렌드셰이프=표정 내부, 행렬=머리 전체 자세, 04장). 이 정렬은 canonical 메시 cm 단위의 metric 공간에서 이뤄진다. 기본 (x,y,z) 정규화 출력과는 다른 산출물이다.

(g) 출력 후처리·역정규화

무엇을 하나. (d)가 낸 ROI 기준 478점을 원본 이미지 기준 정규화 좌표로 되돌리고, 결과 객체를 조립한다.

역정규화는 이렇게 한다. (c)에서 저장한 ROI 변환(회전·스케일·평행이동)을 역으로 적용해 ROI 패치 좌표를 원본 이미지 좌표로 환산한다. 그다음 원본 폭·높이로 다시 0~1 정규화한다. 최종 사용자가 보는 x,y ∈ [0,1]은 원본 이미지 기준이다(픽셀 x = x × 이미지 폭). z는 머리 중심 원점에 대한 상대 깊이이며 절대 거리가 아니다(03장).

smoothing(떨림 완화)은 num_faces==1일 때만 적용된다. 시간축으로 smoothing을 걸어 프레임 간 지터를 줄인다. num_faces>1이면 smoothing이 빠진다(06장).

마지막으로 결과 객체를 조립한다. FaceLandmarkerResultface_landmarks(항상), face_blendshapes(옵션 켰을 때), facial_transformation_matrixes(옵션 켰을 때)를 담아 반환한다. IMAGE/VIDEO는 동기로 반환하고, LIVE_STREAM은 콜백으로 넘긴다(05장·06장).

주경로가 끝났다. 그런데 영상에서는 매 프레임 (b) 검출기를 다 돌릴까? 아니다. 이 결정이 실시간 성능의 핵심이다.

2.3 핵심 통찰 — 왜 검출과 메시를 분리하나

(b)~(d)를 한 문장으로 다시 보면 이렇다. 가벼운 검출기로 위치를 잡고(b), 정확히 잘라 똑바로 세운 뒤(c), 무거운 메시 모델은 정리된 패치에만 집중한다(d). 이 분업이 주는 이득을 그림으로 본다.

split: detect then mesh

detector: small, fast, scans whole frame

mesh: precise, sees only aligned patch

no need to learn rotation/scale invariance

model capacity goes to precision

cheap to run every frame OR skip via tracking

검출기는 큰 화면을 훑느라 비싸다. 그래도 한 번 위치를 잡으면 영상에서는 그 위치를 재사용해 검출기를 건너뛸 수 있다. 이 "한 번 검출, 그다음 추적" 전략이 다음 절의 주제다.

광고 · Advertisements

2.4 검출 vs 추적 — 성능의 결정 요인

같은 모델 번들이라도 언제 검출기를 부르느냐가 실시간 성능을 가른다. 이것이 실행 모드(running_mode)의 본질이다.

두 동작 양식

  • 검출(detection) = 재획득(reacquisition): 화면 전체에서 BlazeFace를 돌려 얼굴을 처음부터 찾는다. 사전 정보가 없는 첫 프레임이나, 추적이 깨졌을 때 쓴다. 전체 화면을 훑으니 비싸다.
  • 추적(tracking): 이전 프레임의 랜드마크로 얼굴 위치·각도를 이미 안다. 그것으로 ROI를 바로 만들어 검출기를 건너뛰고 메시 모델만 돌린다. 작은 패치만 처리하니 싸다.

핵심 직관은 얼굴이 프레임 사이에 거의 안 움직인다는 것이다. 30 FPS면 프레임 간격이 약 33ms다. 그 사이 얼굴은 거의 같은 자리에 있다. 그러니 매 프레임 화면 전체를 새로 뒤질 이유가 없다. 직전 위치를 재사용하면 가장 비싼 단계 중 하나인 검출기를 대부분 프레임에서 생략할 수 있다. 이것이 "detect-once-then-track" 설계의 동기다.

모드별 동작

모드 검출기 호출 추적 반환 비고
IMAGE 매번(단일 이미지) 없음 동기 프레임 간 정보 없음
VIDEO 첫 프레임 + 추적 실패 시 사용 동기(타임스탬프 ms) 디코드된 프레임
LIVE_STREAM 첫 프레임 + 추적 실패 시 사용 비동기 콜백 처리 중 들어온 프레임 drop

IMAGE가 기본값이고, LIVE_STREAM만 result listener 콜백을 쓴다. 세 모드의 호출 방식·API 차이는 05장에서 더 본다.

세 confidence 임계값의 역할

추적 루프를 제어하는 세 임계값은 모두 기본 0.5다. 셋은 서로 다른 단계의 게이트다. 이름이 비슷해 헷갈리기 쉬우니 표로 못 박는다.

임계값 어느 단계 공식 정의(요약) 떨어지면?
min_face_detection_confidence 검출 단계 검출 성공으로 인정할 최소 신뢰도 그 얼굴 후보를 버림
min_face_presence_confidence 랜드마크 단계 랜드마크 단계에서 얼굴 존재로 인정할 최소 신뢰도(메시 모델의 presence flag) 이번 프레임 결과 무효 → 재검출 유도
min_tracking_confidence 추적 단계(VIDEO/LIVE) 추적 성공으로 인정할 최소 신뢰도 추적 중단 → 다음 프레임 검출기 재실행(재획득)

가운데 min_face_presence_confidence는 검출과 추적 사이의 별도 게이트다. 레거시 Face Mesh에는 없던 신규 임계값이다(05장).

왜 이 전략이 성능에 결정적인가. 두 가지 이득이 있다.

추적 모드는 검출기를 매 프레임 생략한다. 프레임당 비용이 메시(+옵션) 추론으로 줄어 지연이 크게 감소한다.

게다가 추적 모드는 정확도도 더 높다. Face Mesh V2 모델 카드 기준으로 tracking 모드 IOD MAE는 2.62%로, reacquisition 3.24%보다 낮다(06장). 직전 프레임으로 잘 정렬된 ROI를 쓰니, 검출에서 새로 시작하는 것보다 정밀하다. 빠르면서 더 정확한 이중 이득이다.

임계값들은 트레이드오프 손잡이다. 너무 낮으면 깨진 추적을 붙잡고 있어 품질이 나빠진다. 너무 높으면 자꾸 재검출해 비용과 지터가 는다.

추적 루프 — 상태도

detection score >= min_face_detection_confidence
and presence flag >= min_face_presence_confidence

tracking score >= min_tracking_confidence
and presence flag OK

tracking score < min_tracking_confidence
or presence flag < threshold (reacquire)

no face found (retry next frame)

run BlazeFace on full frame

reuse prev ROI, skip detector

추적 프레임의 시퀀스

Post-processFace Mesh V2ROI crop and alignBlazeFace detectorFrame sourcePost-processFace Mesh V2ROI crop and alignBlazeFace detectorFrame sourceFrame 1 — reacquisition (no prior info)Frame 2..N — tracking (detector skipped)alt[presence flag >= threshold and tracking OK][presence/tracking below threshold]full frame 192x192bbox + 6 keypointsaligned 256x256 patch478 landmarks + presence flagresult (presence OK, keep ROI for next frame)reuse previous-frame landmarks as ROIaligned 256x256 patch478 landmarks + presence flagresult (keep tracking)re-run detector next frame (reacquire)

두 그림이 이 절의 핵심이다. 첫 프레임만 검출기를 거치고, 이후엔 메시 모델만 돌리는 짧은 루프가 반복된다. 그러다 신뢰도가 떨어지는 순간에만 검출기로 되돌아간다.

흐름을 다 봤으니, 그 사이 좌표가 어느 공간에서 어느 공간으로 옮겨 다녔는지 정리한다.

2.5 좌표·데이터 흐름 — 세 공간을 오간다

파이프라인 내내 좌표는 세 개의 공간을 오간다.

detector finds bbox + keypoints

crop + rotate (ROI transform)

mesh regresses 478 here

inverse ROI transform

x*width, y*height

146 subset (2D)

fit to canonical mesh (cm)

original pixel space (w x h)

original-normalized bbox, keypoints

ROI-normalized space (256x256 patch)

478 landmarks (ROI-normalized)

original-normalized x,y in 0..1

pixel coords (if needed)

blendshape input (1x146x2)

metric/canonical space, 4x4 matrix

핵심을 네 가지로 정리한다.

  1. 원본 픽셀 공간 → 원본 정규화: 검출기가 찾은 bbox·키포인트는 원본 이미지 기준으로 표현된다.
  2. 원본 → ROI 정규화: (c)의 crop·rotate가 좌표를 ROI 패치(256×256) 기준으로 옮긴다. 메시 모델은 이 공간에서만 일한다. 그래서 (d) 출력 478점은 ROI 기준이다.
  3. ROI 정규화 → 원본 정규화: (g)에서 ROI 변환을 역적용해 478점을 원본 이미지 기준 0~1로 되돌린다. 최종 출력은 항상 원본 기준 x,y ∈ [0,1]이고, z는 상대 깊이다(03장 규약과 동일).
  4. 곁가지의 좌표: 블렌드셰이프는 478점 중 146점의 2D 좌표만 떼어 입력 1×146×2로 쓰며, 계수 출력은 좌표가 아니다. 변환행렬은 478 메시를 canonical metric 공간(cm)에 정렬해 4×4를 얻으며, 정규화 (x,y,z)와는 다른 공간이다.

직관으로 풀면 이렇다. 메시 모델은 잘려서 똑바로 세워진 작은 얼굴 사진 안에서만 좌표를 매긴다. 그래서 그 좌표는 그 작은 사진 기준이다. 화면에 점을 찍으려면 그 좌표를 원래 큰 사진 기준으로 되돌려야 한다. 그게 (g) 역정규화다. 되돌릴 수 있는 이유는 (c)에서 어떻게 잘랐고 얼마나 돌렸는지(ROI 변환)를 기록해 뒀기 때문이다.

이 흐름을 MediaPipe가 내부적으로 어떻게 조립하는지, graph/calculator 개념을 마지막으로 가볍게 짚는다.

2.6 MediaPipe graph / calculator — 내부 조립의 큰 그림

이 장에서 본 흐름을 MediaPipe가 내부적으로 어떻게 조립하는지 큰 그림만 본다. 깊이 들어갈 필요는 없다.

  • graph(그래프): MediaPipe는 처리 과정을 방향성 비순환 그래프(DAG)로 모델링한다. 노드들이 데이터 스트림으로 연결돼 한 방향으로 흐른다.
  • calculator(계산기): 그래프의 각 노드다. 입력 스트림을 받아 출력 스트림을 내는 자기완결적 처리 단위다. 이미지 리사이즈, 텐서 추론, 텐서→랜드마크 변환, ROI 자르기, 역정규화 같은 작업이 각각 calculator다.
  • 이 장의 단계와 calculator의 대응: (a) 전처리, (c) ROI crop, (d) 텐서 추론, (g) 역정규화 같은 단계들은 실제로는 여러 calculator가 이어진 서브그래프로 구현돼 있다.
  • .task 번들의 정체: Tasks API에서 사용자는 calculator 그래프를 직접 짜지 않는다. face_landmarker.task 번들이 모델 3종(tflite)과 그래프·메타데이터를 함께 담아 둔다. 사용자는 옵션만 주면 내부에서 적절한 calculator 그래프가 구성·실행된다.

.task bundle

BlazeFace tflite

Face Mesh V2 tflite

Blendshape V2 tflite

graph + metadata

calculator graph (DAG)

image preprocess calc

detection inference calc

ROI crop and transform calc

mesh inference calc

tensors to landmarks calc

de-normalize + smoothing calc

FaceLandmarkerResult

한 줄로 정리하면 calculator는 작은 처리 블록, graph는 그 블록들을 잇는 배선도, .task는 모델과 배선도를 한 봉투에 담은 것이다. 위 그림은 단순화한 개념도이며, 실제 calculator 단위의 정확한 그래프 토폴로지와는 다를 수 있다. Tasks API 사용자는 봉투만 열어 쓰고, 내부 배선은 신경 쓰지 않아도 된다.

2.7 전체를 한 흐름으로

이 장 전체를 단계 순서로 다시 본다.

  1. (a) 전처리: RGB 이미지를 RGB로 정리하고 검출기용 192×192로 리사이즈한다.
  2. (b) 검출: BlazeFace short-range가 192×192에서 bbox와 6 키포인트로 얼굴을 거칠게 찾는다.
  3. (c) ROI 정렬: 그 키포인트로 얼굴을 잘라 두 눈이 수평이 되게 회전·정규화한 256×256 패치를 만든다.
  4. (d) 회귀: Face Mesh V2가 그 패치에서 478점을 ROI 기준으로 회귀한다. 눈·입술·홍채는 Attention으로 정제한다.
  5. (e) 블렌드셰이프(옵션): 146점 서브셋을 별도 Blendshape V2가 받아 52 계수를 낸다.
  6. (f) 변환행렬(옵션): 메시를 canonical 모델에 정렬해 4×4 머리 자세 행렬을 낸다.
  7. (g) 후처리: ROI 좌표를 원본 기준 0~1로 역정규화하고, num_faces=1이면 smoothing해 결과 객체로 반환한다.

영상에서는 이 흐름이 한 번 더 빨라진다. VIDEO/LIVE_STREAM에서는 첫 프레임만 (b)를 거친다. 이후엔 직전 랜드마크로 ROI를 재사용해 (b)를 건너뛴다. presence나 tracking 신뢰도가 0.5 아래로 떨어질 때만 검출기로 되돌아간다. 이 detect-once-then-track이 실시간 성능과 정확도를 동시에 끌어올리는 핵심이다.

이 파이프라인의 주산물인 478점이 정확히 무엇이고 왜 478개인지를 다음 장에서 확대한다.

다음 장: 03. 478개 랜드마크 — 종류와 "왜 478개인가"


Sources

  • Face Landmarker 가이드 (Google AI Edge) — 3개 모델(검출 192×192 / 메시 256×256 / blendshape 1×146×2), presence/detection/tracking confidence 정의, 변환행렬 정의("transform the face landmarks from a canonical face model to the detected face"): https://ai.google.dev/edge/mediapipe/solutions/vision/face_landmarker
  • Face Detector 가이드 (BlazeFace short-range) — 6 키포인트("left eye, right eye, nose tip, mouth, left eye tragion, and right eye tragion"), short/full-range 구분, Pixel 6 CPU 2.94 ms / GPU 7.41 ms, 독립 가이드의 128×128 표기: https://ai.google.dev/edge/mediapipe/solutions/vision/face_detector
  • BlazeFace: Sub-millisecond Neural Face Detection on Mobile GPUs (arXiv:1907.05047) — 경량 single-shot 검출기, 회전 2D bounding rectangle + anchor 점으로 "정확한 얼굴 ROI를 요구하는 task-specific 모델"에 연결되도록 설계: https://arxiv.org/abs/1907.05047
  • MediaPipe: A Framework for Building Perception Pipelines (arXiv:1906.08172) — graph(DAG)·calculator(self-contained 입력/출력 스트림 처리 단위) 개념: https://arxiv.org/abs/1906.08172
  • Attention Mesh (arXiv:2006.10962) — 478 메시 예측 후 입술·양안 ROI region refinement(고해상도 정제), 단일 네트워크 ~30% 빠름: https://arxiv.org/abs/2006.10962
  • MediaPipe BlazePose 블로그(Google Research) — detect-once-then-track(첫 프레임 검출, 이후 직전 ROI 재사용) 전략의 근거: https://research.google/blog/on-device-real-time-body-pose-tracking-with-mediapipe-blazepose/
  • Model Card — MediaPipe Face Mesh V2 — 입력 256×256(25% 마진 크롭), 478 랜드마크, MobileNetV2-like, tracking/reacquisition IOD MAE 2.62%/3.24%, 모델 날짜 2022-09-15: https://storage.googleapis.com/mediapipe-assets/Model%20Card%20MediaPipe%20Face%20Mesh%20V2.pdf

표기 규약: 검출기 입력 해상도는 번들 기준 192×192를 따른다(06장 확정). 독립 Face Detector 가이드의 128×128 표기와의 차이는 (a) 단계에 명시했다. ROI 정렬·역정규화의 단계 분해는 공식 문서의 단편적 서술(내부 정렬됨·정확히 크롭된 ROI)과 MediaPipe 파이프라인 일반 구조에 근거한 재구성이며, calculator 단위의 정확한 그래프 토폴로지는 단순화한 개념도다.