사전 3D 재현
개념

3D 재현

gabury1고친 사람 github-actions[bot]

3D 재현은 여러 장의 사진으로 물체나 장면의 입체 모양을 되살리는 일입니다. 사진 한 장에는 물체가 얼마나 멀리 있었는지가 남지 않습니다. 그래서 다른 곳에서 찍은 사진 여러 장을 맞대어 그 거리를 계산합니다. 장면에서 그림을 만드는 그래픽스를 거꾸로 거슬러 가는 일입니다.

쉽고 빠른 이해

3D 재현은 사진 여러 장을 받아 입체 모형을 만들어 냅니다. 조각상 둘레를 돌며 휴대폰으로 찍은 사진 서른 장에서 그 조각상의 입체 모형을 얻는 일이 그 예입니다.

이게 없으면 입체 모형은 사람이 손으로 빚어야 합니다. 줄자로 잽니다. 모델링 프로그램에서 면을 하나씩 그려야 합니다.

어떻게 도나:

  1. 사진마다 눈에 띄는 점을 찾고, 여러 사진에 함께 찍힌 같은 점끼리 짝을 짓습니다
  2. 짝지은 점들로 사진을 찍은 곳과 점의 입체 위치를 함께 계산합니다
  3. 듬성듬성한 점을 촘촘하게 채운 뒤 그 위에 겉면을 입힙니다

대가도 있습니다. 계산할 것이 많아 오래 걸립니다. 흰 벽이나 유리처럼 무늬가 없거나 비치는 면은 구멍으로 남습니다. 사진만으로는 실제 크기를 몰라서 길이를 아는 물건을 함께 찍어야 합니다.

상세

한쪽 눈을 감고 팔을 뻗어 연필 끝으로 컵 가장자리를 짚어 보면 자꾸 앞이나 뒤로 빗나갑니다. 두 눈을 뜨면 한 번에 짚습니다.

이 절은 3D(three-dimensional, 3차원) 재현이 두 눈의 일을 사진기로 어떻게 해내는지 봅니다. 먼저 사진 한 장이 무엇을 잃는지 봅니다. 다음은 사진 두 장으로 거리를 되찾는 계산입니다. 이어서 사진기 위치를 모를 때 쓰는 방법과 결과가 점에서 겉면이 되는 단계입니다. 끝으로 그래픽스와의 관계와 백엔드 개발자가 이 일을 만나는 때를 봅니다.

예로는 박물관 조각상 하나를 계속 씁니다. 휴대폰을 들고 조각상 둘레를 한 바퀴 돌며 사진 서른 장을 찍었습니다. 목표는 이 사진들로 조각상의 입체 모형을 얻는 것입니다.

3D 재현이 없으면 이런 모형은 사람이 손으로 빚어야 합니다. 줄자로 조각상을 잽니다. 모델링 프로그램에서 면을 하나씩 그립니다. 3D 재현은 이 일을 사진 몇십 장과 계산으로 바꿉니다.

사진 한 장이 잃는 깊이

사진기는 입체인 장면을 평평한 사진 한 장에 옮겨 담습니다. 이렇게 3차원의 점을 2차원 평면에 떨어뜨리는 일을 원근 투영이라고 부릅니다. 가까운 것은 크게, 먼 것은 작게 찍히는 것이 이 투영 때문입니다.

투영을 계산하는 기본 모형은 핀홀 카메라입니다. 장면의 점에서 나온 빛이 바늘구멍 하나를 지나 뒤쪽 면에 맺힌다고 봅니다. 그러면 사진 위의 점 하나는 바늘구멍에서 장면 쪽으로 뻗은 직선 하나에 대응합니다.

문제는 그 직선 위의 점이 모두 사진의 같은 점에 찍힌다는 것입니다. 조각상 코끝이 1미터 앞에 있든 2미터 앞에 있든, 같은 직선 위에 있으면 사진에서는 같은 픽셀입니다. 픽셀은 사진을 이루는 작은 점 하나입니다.

사진 한 장은 방향만 남기고 거리를 지웁니다. 사진기에서 물체까지의 이 거리를 깊이라고 부릅니다. 3D 재현은 이 지워진 깊이를 되찾는 일입니다.

두 직선이 만나는 점

사진 두 장이 있으면 지워진 깊이를 되찾을 수 있습니다. 조각상 코끝이 두 사진에 모두 찍혔다고 해 봅니다. 사진마다 코끝으로 향하는 직선이 하나씩 나옵니다.

두 사진을 찍은 곳이 다르므로 두 직선은 한 점에서 만납니다. 그 점이 코끝의 입체 위치입니다. 이렇게 두 곳에서 본 방향으로 위치를 계산하는 일을 삼각측량이라고 부릅니다.

사진에는 잡음이 섞여서 두 직선은 대개 살짝 엇갈립니다. 그래서 두 직선 모두에 가장 가까운 점을 답으로 고릅니다.

직선을 그으려면 사진기가 어디에 섰고 어느 쪽을 향했는지 알아야 합니다. 이 값을 외부 파라미터라고 부릅니다. 같은 픽셀이라도 사진기가 돌아가 있으면 직선이 전혀 다른 쪽으로 뻗기 때문입니다.

렌즈와 센서가 정하는 값도 필요합니다. 대표가 초점 거리입니다. 핀홀 카메라로 치면 바늘구멍에서 상이 맺히는 면까지의 거리입니다. 초점 거리가 길수록 같은 물체가 사진에 크게 찍힙니다.

초점 거리처럼 사진기 안쪽이 정하는 값들이 내부 파라미터입니다. 이 값들을 미리 재 두는 일을 카메라 캘리브레이션이라고 합니다.

시차로 거리 계산하기

나란히 놓은 사진기 두 대로 같은 장면을 동시에 찍는 방식을 스테레오 비전이라고 부릅니다. 두 눈과 같은 배치입니다. 이 배치에서는 삼각측량이 나눗셈 하나로 줄어듭니다.

같은 점이라도 왼쪽 사진과 오른쪽 사진에서 찍힌 가로 위치가 조금 다릅니다. 이 차이를 시차라고 부릅니다. 시차는 픽셀 수로 셉니다. 가까운 물체일수록 시차가 큽니다. 먼 물체일수록 작습니다.

거리는 초점 거리와 두 사진기 사이 거리를 곱한 뒤 시차로 나누면 나옵니다. 이때 초점 거리는 미터가 아니라 픽셀 수로 적습니다. 바늘구멍에서 상이 맺히는 면까지가 픽셀 몇 개 너비인지를 센 값입니다.

시차도 픽셀 수이므로 나눗셈에서 픽셀끼리 지워지고 미터만 남습니다. 아래는 이 계산을 숫자로 한 번 해 본 것입니다.

JavaScript
const f = 700;  // 초점 거리(픽셀)
const B = 0.1;  // 두 사진기 사이(m)
const d = 35;   // 시차(픽셀)
const Z = f * B / d;  // 2 (m)

시차가 35 픽셀이면 조각상은 2미터 앞에 있습니다. 시차가 70 픽셀로 늘면 거리는 1미터로 줄어듭니다. 시차와 거리는 반비례합니다.

이 반비례 때문에 먼 물체는 재기 어렵습니다. 먼 물체는 시차가 몇 픽셀밖에 안 되어서, 시차를 한 픽셀만 잘못 재도 거리가 크게 빗나갑니다. 두 사진기를 더 멀리 떨어뜨리면 시차가 커져 먼 곳도 더 잘 잽니다.

같은 점을 짝짓는 일

삼각측량은 두 사진에서 같은 점을 찾았다는 전제 위에 섭니다. 코끝이 첫째 사진의 어느 픽셀이고 둘째 사진의 어느 픽셀인지 알아야 직선 두 개를 긋습니다. 이 짝을 찾는 문제를 대응 문제라고 부릅니다.

짝을 찾으려면 먼저 사진마다 다시 찾기 쉬운 점을 고릅니다. 모서리나 무늬가 꺾이는 곳처럼 주변과 뚜렷이 다른 점입니다. 이런 점을 특징점이라고 부릅니다.

특징점마다 그 둘레의 생김새를 숫자 묶음으로 적어 둡니다. 그리고 숫자 묶음이 비슷한 점끼리 짝을 짓습니다. 조각상 왼쪽 눈가의 주름은 어느 사진에서 봐도 비슷한 숫자 묶음을 냅니다.

짝이 나오려면 이웃한 사진끼리 같은 부분이 넉넉히 겹쳐야 합니다. 조각상 앞모습만 찍은 사진과 뒷모습만 찍은 사진 사이에는 짝지을 점이 없습니다. 그래서 둘레를 돌며 조금씩 옮겨 가며 찍습니다.

무늬가 없는 면에서는 짝짓기가 막힙니다. 흰 벽은 어디를 잘라 봐도 생김새가 같아서 짝을 고를 수 없습니다. 유리나 광택 금속처럼 비치는 면은 보는 곳에 따라 다른 것이 비쳐서 짝이 틀립니다. 이런 곳은 결과 모형에 구멍이나 엉뚱한 돌기로 남습니다.

사진기 위치까지 함께 푸는 방법

휴대폰으로 돌며 찍은 사진에는 사진기 위치가 적혀 있지 않습니다. 그래서 점의 위치와 사진기 위치를 한꺼번에 계산하는 방법을 씁니다. 이 방법을 SfM(Structure from Motion, 움직임에서 구조 찾기)이라고 부릅니다.

SfM 은 아래 순서로 돕니다.

flowchart TD
    A["사진 여러 장"] --> B["사진마다 특징점 찾기"]
    B --> C["사진끼리 같은 점 짝짓기"]
    C --> D["사진기 위치와 점 위치를 함께 계산"]
    D --> E["번들 조정 · 전체 오차 줄이기"]
    E --> F["성긴 입체 점들"]

계산은 사진 두 장에서 시작합니다. 같은 점이 두 사진의 어디에 찍히는지는 두 사진기가 어떻게 놓였느냐에 따라 달라집니다. 그래서 짝지은 점이 넉넉히 있으면, 그 짝을 모두 들어맞게 하는 두 사진기의 배치는 크기만 빼고 하나로 좁혀집니다. 이렇게 두 사진기가 서로 어떻게 놓였는지를 먼저 계산합니다.

두 사진기의 배치를 알면 짝마다 직선 두 개를 그을 수 있습니다. 이 두 사진기로 점 몇백 개의 위치를 삼각측량합니다. 그다음 위치를 아는 점이 찍힌 사진을 하나씩 더하며 사진기와 점을 늘려 갑니다.

사진을 더할수록 작은 오차가 쌓입니다. 그래서 마지막에 모든 사진기와 모든 점을 한꺼번에 조금씩 옮깁니다. 계산한 점을 각 사진에 다시 투영했을 때 처음 찍힌 픽셀과 가장 잘 맞도록 옮기는 것입니다. 이 마무리를 번들 조정이라고 부릅니다.

사진을 다 모은 뒤가 아니라 움직이면서 그때그때 SfM 같은 계산을 하는 갈래도 있습니다. 로봇이나 증강 현실 기기가 자기 위치와 주변 지도를 동시에 그려 나가는 SLAM(Simultaneous Localization and Mapping, 동시적 위치 추정과 지도 작성)이 그렇습니다.

사진만으로는 모르는 크기

SfM 의 결과에는 실제 크기가 없습니다. 조각상과 사진기 사이 간격을 모두 두 배로 키워도 사진은 똑같이 찍히기 때문입니다. 그래서 결과는 모양은 맞지만 미터 같은 단위가 없는 모형입니다.

스테레오 비전은 이 문제가 없습니다. 두 사진기 사이 거리를 미리 알고 계산에 넣기 때문입니다. SfM 에서 실제 크기가 필요하면 길이를 아는 자를 함께 찍거나, 두 지점 사이 거리를 따로 재서 모형에 맞춥니다.

성긴 점에서 겉면까지

SfM 이 내놓는 것은 특징점 수천 개의 입체 위치입니다. 이렇게 입체 좌표를 가진 점들의 모음을 포인트 클라우드라고 부릅니다. 점 구름이라고도 합니다. 특징점만 계산했으므로 아직 듬성듬성합니다.

다음 단계는 점을 촘촘하게 채우는 일입니다. 이제 사진기 위치를 알므로 짝을 찾아볼 범위가 좁아집니다. 한 사진의 픽셀에서 뻗은 직선은 이웃 사진에 선 하나로 찍힙니다. 짝은 그 선 위 어딘가에 있습니다. 사진 전체를 뒤지지 않고 그 선 위만 견주면 되니, 특징점이 아닌 픽셀도 짝을 찾아 깊이를 계산할 수 있습니다.

이 단계를 다시점 스테레오라고 부릅니다. 줄여서 MVS(Multi-View Stereo)라고도 합니다. 결과는 조각상 겉면을 빽빽이 덮는 점 구름입니다.

점은 아무리 많아도 겉면이 아닙니다. 화면에 그리거나 3D 프린터로 뽑으려면 점들을 이어 작은 삼각형으로 겉면을 만들어야 합니다. 이렇게 만든 겉면을 메시라고 부릅니다.

끝으로 사진의 색을 메시 위에 입힙니다. 메시에 입히는 이 색 그림을 텍스처라고 부릅니다. 그러면 조각상과 같은 빛깔의 모형이 됩니다.

단계마다 손에 쥐는 결과가 달라집니다. 아래 표가 조각상 사진 서른 장이 거치는 단계와 그 결과입니다.

단계 손에 쥐는 결과
SfM 사진기 서른 대의 위치와 듬성듬성한 점 구름
다시점 스테레오 겉면을 빽빽이 덮는 점 구름
겉면 만들기 삼각형으로 이은 메시
색 입히기 텍스처를 입힌 메시

사진 대신 깊이를 직접 재는 센서

지금까지 본 방법은 빛을 받기만 하는 사진기로 깊이를 계산합니다. 이런 쪽을 수동 방식이라고 부릅니다. 다른 길은 센서가 빛을 쏘고 되돌아오는 것을 재서 깊이를 바로 얻는 것입니다. 이쪽은 능동 방식입니다.

방식 깊이를 얻는 법 막히는 곳
사진기 여러 장 · 수동 사진을 맞대어 시차와 삼각측량으로 계산 무늬 없는 면 · 비치는 면
구조광 · 능동 정해진 무늬를 비추고 그 무늬가 찌그러진 모양을 읽음 햇빛이 무늬를 덮는 바깥
라이다 · 능동 레이저를 쏘고 되돌아오는 시간을 잼 장비 값 · 빛을 삼키는 검은 면 · 유리

능동 방식은 흰 벽에서도 깊이를 얻습니다. 자기가 쏜 빛을 기준으로 재므로 무늬가 필요 없기 때문입니다. 그래서 흰 벽이 많은 실내나 치수가 정밀해야 하는 일에는 능동 센서를 고르는 일이 많습니다. 대신 센서가 따로 있어야 합니다. 사진기만큼 흔하지도 않습니다.

그래픽스와 반대 방향

그래픽스는 장면의 모양과 사진기 위치를 정해 두고 그림을 만듭니다. 3D 재현은 그림에서 출발해 장면의 모양과 사진기 위치를 알아냅니다. 둘은 같은 사진기 모형을 씁니다. 방향만 반대입니다.

번들 조정이 점을 사진에 다시 투영해 보는 계산은 그래픽스가 그림을 그릴 때 하는 투영과 같은 식입니다. 3D 재현은 그 식을 거꾸로 풉니다. 제대로 풀었는지는 다시 앞으로 그려 보며 확인합니다.

3D 재현은 컴퓨터 비전의 한 갈래입니다. 그중 그래픽스와 가장 가까이 맞닿습니다. 3D 재현이 내놓은 메시와 텍스처는 그대로 그래픽스의 입력이 됩니다. 조각상 모형을 웹 페이지에서 돌려 보게 하는 것은 그래픽스의 일입니다.

백엔드 개발자가 이 일을 만나는 때

서비스에서 3D 재현은 흔히 사진을 올리면 모형을 돌려주는 기능으로 나타납니다. 사용자가 휴대폰으로 찍은 사진 수십 장을 올립니다. 서버는 모형 파일을 만들어 돌려줍니다. 부동산 앱에서 방 사진 마흔 장을 올리면 그 방을 돌려 볼 수 있는 모형 파일 하나가 돌아오는 기능이 그런 예입니다.

재현 한 번은 사진 짝을 맞춰 보고 번들 조정까지 돌리느라 보통의 요청 처리보다 훨씬 오래 걸립니다. 점을 촘촘하게 채우는 단계는 GPU(Graphics Processing Unit, 그래픽 처리 장치)를 쓰는 일이 많습니다.

그래서 업로드 요청은 사진을 받아 저장한 뒤 바로 끝냅니다. 재현은 작업 큐에 넣어 따로 도는 작업자가 맡습니다. 끝나면 사용자에게 알리거나 상태를 조회하게 합니다. 요청과 처리를 이렇게 떼어 두는 것이 비동기 처리입니다.

결과물은 크기가 큰 파일입니다. 그래서 데이터베이스보다 오브젝트 스토리지에 둡니다. 웹에서 보여 줄 때는 glTF(GL Transmission Format, 3D 모형 전송 형식) 같은 형식으로 바꿔 내려보냅니다.

업로드 단계에서 미리 거를 것도 있습니다. 사진 수가 너무 적거나 이웃한 사진끼리 겹치는 부분이 없으면 짝을 못 찾아 재현이 실패합니다. 오래 걸리는 작업을 돌리기 전에 이런 입력을 돌려보내면 작업자의 시간을 아낍니다.

관련 항목

3D 재현이 거치는 처리 단계

특징점 · 특징 검출기 · 특징 매칭 · 대응 문제 · 삼각측량 · 번들 조정 · 다시점 스테레오 · 표면 재구성 · 텍스처 매핑

3D 재현을 푸는 방식

SfM · 스테레오 비전 · SLAM · 시각 오도메트리 · 깊이 추정 · NeRF · 3D 가우시안 스플래팅

3D 재현이 기대는 사진기 모형

카메라 · 핀홀 카메라 · 원근 투영 · 외부 파라미터 · 내부 파라미터 · 카메라 캘리브레이션 · 렌즈 왜곡 · 에피폴라 기하

3D 재현이 내놓는 결과 형식

포인트 클라우드 · 깊이 맵 · 메시 · 텍스처 · 복셀 · glTF · PLY · OBJ

3D 재현에 깊이를 직접 대 주는 센서

깊이 카메라 · 구조광 · ToF 카메라 · 라이다

3D 재현 결과를 받아 그리는 그래픽스 요소

그래픽스 · 렌더링 · 그래픽스 파이프라인 · 씬 그래프 · 래스터화

3D 재현과 같은 사진기 모형을 쓰는 분야

컴퓨터 비전 · 사진 측량 · 로봇 공학 · 원격 탐사

3D 재현을 채택한 응용 분야

증강 현실 · 가상 현실 · 자율 주행 · 디지털 트윈 · 문화유산 디지털화 · 게임 개발 · 시각 효과

3D 재현 작업을 서비스로 굴리는 수단

작업 큐 · 비동기 · GPU · 오브젝트 스토리지 · 배치 처리

다른 이름: 3D reconstruction · 3차원 복원 · 3D 복원 · 3차원 재구성