"진짜 두개골에서 눈이 어디 있는지 알아. 사진에서 어디 떨어졌는지도 알아. solvePnP 가 물어: 무슨 카메라가 앞엣걸 뒤엣걸로 바꾸나?"
solvePnP 가 답하는 질문
Perspective-n-Point — solvePnP — 는 앞 레슨의 정확한 역이야. 정방향 투영은 pose 를 받아 픽셀을 냈어. solvePnP 는 픽셀을 받아 pose 를 내. 구체적으로: 레퍼런스 머리 위 위치를 아는 3D 점들이 있고, 그 같은 이목구비가 사진에 떨어진 2D 픽셀이 있어. 솔버는 그 3D 점들을 pinhole 모델로 돌렸을 때 정확히 그 픽셀들로 투영했을 단 하나의 회전과 이동을 찾아. 그 회전이 머리의 방향이야 — 눈대중이 아니라 계산된 투시 상자.
대응이 연료야
솔버는 대응(correspondences) — (2D 픽셀, 3D 점) 매칭 쌍 — 으로 돌아. 3D 반쪽은 canonical 머리에서 와 — 모든 landmark 의 위치를 아는 중립 레퍼런스 얼굴. 2D 반쪽은 검출기(다음 트랙)에서 와, 그 landmark 각각이 이 사진에 실제로 나타난 자리를 알려줘. 인덱스로 매칭돼: 사진의 landmark 33 이 모델의 점 33 과 짝지어. 그 인덱스 매칭이 검출기 출력과 레퍼런스 모델이 topology-lock 을 유지해야 하는 이유야 — 인덱스를 바꾸거나 드리프트시키면 모든 대응이 조용히 거짓말해.
reprojection error 최소화
보통 모든 픽셀을 완벽히 맞추는 pose 는 없어 — 진짜 얼굴은 중립 모델이 아니고, 검출은 노이지해. 그래서 solvePnP 는 가장 가까운 pose 를 찾아: 총 reprojection error, 즉 3D 점이 투영돼 떨어지는 자리와 실제 관측된 자리 사이 픽셀 거리의 합을 최소화해. 그 남은 error 는 부산물만이 아냐 — 엔진의 정직 계기야. 작은 error 는 pose 가 얼굴을 잘 설명한다는 뜻; 큰 건 fit 이 무리했으니 덜 믿어야 한다는 뜻. 솔버가 최소화하는 그 숫자가 UI 가 나중에 confidence 로 보여주는 숫자야.
회전에서 상자로
솔버는 회전을 압축된 형태(회전 벡터)로 돌려주고, 그건 머리의 상자 방향인 3x3 회전 행렬로 변환돼. 그 행렬을 사람이 읽는 yaw, pitch, roll 로 바꾸는 건 그 자체로 작은 지뢰밭이야 — 순진한 분해는 거의 정면인 얼굴에서 wrap 되고 거짓말해 — 그래서 Loomis 는 대신 머리의 forward, up 벡터에서 각도를 읽어. 그 조심스러움이 두 레슨 뒤 no-flip 레슨의 주제 전부야; 지금은 깔끔한 버전을 붙들어: 대응 in, pose out, error 는 영수증.