본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

pinhole 카메라

~13 min · pinhole, projection, perspective, forward-model

Level 0빈 종이
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"카메라는 깊이를 버리는 기계야. 되찾으려면 그게 어떻게 버려졌는지부터 알아야 하고."

카메라는 눌러서 납작하게 만드는 기계다

사진은 입체 세계가 평면에 눌린 결과야. 누르는 규칙은 냅킨 한 장에 적을 만큼 단순하고. pinhole 카메라 모델이라고 불러. 장면의 빛이 아주 작은 구멍 하나를 지나 뒤쪽 평평한 센서에 닿는다고 상상하면 돼. 3D 점 하나가 그 구멍을 지나는 직선을 따라 픽셀 하나에 정확히 떨어져. 모델은 이게 전부야. 그리고 정확하니까 거꾸로도 돌릴 수 있어.

깊이로 나눈다

중요한 연산은 딱 하나, 깊이로 나누는 거야. 카메라가 (X, Y, Z) 자리에서 보는 점이 있다고 하자. Z 가 거리야. 이 점의 픽셀은 x = 초점거리 × X / Z, y = 초점거리 × Y / Z 로 나오고, 이미지 중심만큼 옮겨 놓으면 끝이야. 저 작은 / Z 하나가 투시의 전부지. 거리가 두 배가 되면 중심에 두 배 가깝게 찍히고 크기는 반이 돼. 철길이 모여 보이는 건 옆으로 벌어진 간격은 그대로인데 Z 만 커져서고, 렌즈 앞의 코가 커 보이는 건 Z 가 작아서야. 네가 그려본 모든 투시 효과가 이 나누기 하나에서 나와.

안쪽 값과 바깥쪽 값

투영은 두 덩어리로 나뉘어. 바깥쪽 값인 회전 R 과 이동 t머리가 카메라에 대해 어디 있는지를 말해. Loomis 가 원하는 게 이거고. 안쪽 값인 초점거리와 주점은 카메라 자체를 말하지. 픽셀은 3D 점이 먼저 바깥쪽 값을 지나 카메라 기준으로 옮겨진 다음, 안쪽 값을 지나 깊이로 나뉜 결과야. 이 둘을 머릿속에서 갈라놓고 있어. 카메라 계산은 결국 '안쪽 값은 대충 고정해두고 바깥쪽 값을 푼다' 로 요약되거든.

여기까지가 정방향

이 레슨은 전부 3D 에서 픽셀로 가는 쪽, 그러니까 쉬운 방향이야. Loomis 는 반대편에 살아. 픽셀을 갖고 R 을 되찾아야 하지. 근데 그 반대 방향이 풀리는 이유가 정방향 모델이 이만큼 깔끔하고 정확해서야. 투영을 앞에서부터 이해하고 나면 다음 레슨의 solvePnP 가 블랙박스이기를 그만두고 '이 나누기를 되돌리는 것' 이 돼.

Code

3D 점에서 픽셀까지, 정방향 모델 전부·python
import numpy as np

def project(point_3d, R, t, focal, center):
    # EXTRINSICS: put the point into the camera's frame (where the head sits)
    cam = R @ point_3d + t            # (X, Y, Z) as the camera sees it

    # INTRINSICS: the pinhole divide-by-depth (the camera itself)
    x = focal * cam[0] / cam[2] + center[0]   # <-- divide by Z => perspective
    y = focal * cam[1] / cam[2] + center[1]
    return np.array([x, y])           # a pixel

# Foreshortening, converging rails, a looming nose -- ALL of it is that
# single `/ cam[2]`. Delete the divide and you get flat orthographic projection.

External links

Exercise

팔을 뻗어 펜을 들고 한쪽 눈을 감아. 그다음 펜을 천천히 눈 쪽으로 가져와. 커 보이지. 펜은 하나도 안 변했고 거리 Z 만 줄었을 뿐이야. 보이는 크기가 1/Z 로 간다는 뜻이지. 이제 같은 말로 철길이 왜 지평선에서 만나 보이는지 설명해봐.
Hint
펜의 실제 크기는 고정이고 보이는 크기는 크기 나누기 Z 야. Z 를 반으로 줄이면 두 배로 커 보이지. 철길은 옆으로 벌어진 간격이 고정인데 멀어질수록 Z 가 계속 커져. 그래서 화면에 찍히는 간격이 0 으로 줄고, Z 가 사실상 무한인 자리에서 만나 보이는 거야. 같은 나누기가 만든 두 가지 착시고.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.