컴퓨터 그래픽스 소프트웨어 마지막 수정: 2026-09-14 04:49:52

1. 개요[편집]

COLMAP
정체범용 SfM + MVS 파이프라인 (GUI + CLI + 라이브러리)
원 논문Schönberger & Frahm, Structure-from-Motion Revisited, CVPR 2016
MVS 논문Schönberger 외, Pixelwise View Selection for Unstructured MVS, ECCV 2016
방식점진적(incremental) SfM — 사진을 한 장씩 붙이며 BA 반복
내부 부품SIFT 특징 · RANSAC 기하 검증 · Ceres 기반 번들 조정
현대적 위치신경 렌더링 계열의 카메라 자세 전처리 표준

COLMAP정렬되지 않은 사진 뭉치로부터 카메라 자세와 3차원 구조를 복원하는 Structure-from-Motion(SfM)과 다중 시점 스테레오(MVS)를 하나로 묶은 오픈소스 파이프라인이다. 요하네스 쇤베르거와 얀-미하엘 프람이 2016년 CVPR에 발표한 Structure-from-Motion Revisited 가 원 논문이고, 이름의 유래는 저자들이 속했던 연구 맥락의 약칭이다.

Structure from Motion문제라면 COLMAP은 그 문제의 레퍼런스 구현이다. 그래서 이 문서는 SfM 일반론(에피폴라 기하, 점진적 대 전역, 축퇴 구성 등)을 반복하지 않는다. SfM 문서가 “무엇을 푸는가”를 다뤘으니, 여기서는 “이미 알려진 파이프라인을 실제로 돌아가게 만든 공학적 세부가 무엇이었나” 를 본다. 논문 제목이 “Revisited”인 이유가 정확히 그것이다 — 새 이론을 제안한 논문이 아니라, 기존 파이프라인이 왜 야생 데이터에서 무너지는지를 단계별로 진단하고 각각에 처방을 붙인 논문이다.

2. 왜 “Revisited”인가[편집]

2016년 시점에 SfM은 이미 교과서에 있었다. 그런데 공개된 구현들은 사진이 수천 장 넘어가거나 인터넷에서 긁어온 지저분한 데이터를 만나면 조용히 망가졌다. 논문이 지목한 실패 지점과 처방은 대략 이렇게 정리된다.

실패 지점증상COLMAP의 처방
기하 검증이 느슨함워터마크·타임스탬프가 만드는 가짜 대응이 검증을 통과다중 모형 검증 + 경계 영역 인공물 탐지
다음 뷰를 아무렇게나 고름조건수 나쁜 자세 추정 → 드리프트 누적점 개수와 화면상 분포를 함께 보는 다해상도 점수
삼각측량이 취약오대응 하나가 점을 엉뚱한 곳에 만듦트랙 전체에 RANSAC을 건 다시점 삼각측량
BA를 한 번 돌리고 끝버려진 관측이 영원히 버려짐재삼각측량을 BA 전후로 반복
전역 BA 비용 폭발사진 수에 초선형중복 시점 군집화로 파라미터 축약

이 목록의 성격을 보면 알 수 있다. 전부 “논문에 안 적히던 것들”이다. 실제로 이 분야에서 재현성이 가장 낮았던 부분이 바로 이 층이었고, 그것을 체계적으로 적고 코드로 공개한 것이 COLMAP이 표준이 된 이유다.1

2.1. 장면 그래프 증강과 경계 인공물[편집]

기하 검증 단계에서 COLMAP은 각 영상 쌍에 기초행렬 FF, 본질행렬 EE, 호모그래피 HH 를 모두 맞춰 보고 내점 수를 비교해 쌍의 성격을 분류한다(일반 이동 / 평면 또는 순수 회전 / 보정 여부). 분류 결과가 그대로 다음 단계의 사용 방식을 바꾼다.

여기에 덧붙은 실전적 장치가 인터넷 사진에서 악명 높은 워터마크·타임스탬프·액자 테두리 처리다. 이런 것들은 사진 내용과 무관하게 항상 같은 화소 위치에 찍히므로, 전혀 다른 장면을 찍은 두 사진 사이에도 내점이 수백 개 나오는 대응을 만든다. 기하 검증은 이것을 완벽한 매칭으로 판정하고, 결과는 관계없는 사진 두 장이 한 덩어리로 붙는 참사다. COLMAP은 영상 경계 영역의 대응들이 순수한 평행이동·유사변환으로 설명되는지를 따로 검사해 이런 쌍을 걸러낸다.2

2.2. 다음 뷰 선택 — 개수가 아니라 분포[편집]

어떤 사진을 다음에 등록할지 고를 때, 순진한 기준은 “이미 복원된 3차원 점을 가장 많이 보는 사진”이다. 그런데 그 점들이 화면 한구석에 몰려 있으면 PnP 자세 추정의 조건수가 나빠서 오차가 크게 들어온다. COLMAP은 영상을 Kl×KlK_l \times K_l 격자로 나누되 여러 해상도 단계에서 나누고, 점이 차지한 칸에 해상도별 가중치를 매겨 합산한 점수를 쓴다. 점이 적어도 고르게 퍼져 있으면 높은 점수를 받는다.

효과가 나오는 자리가 명확하다. 자세 오차는 등록될 때마다 누적되므로, 조건수 나쁜 등록 하나가 그 이후 모든 등록의 기준을 망친다. 좋은 순서로 붙이는 것이 사후 BA로 고치는 것보다 훨씬 싸다는 것이 이 설계의 논리다.

2.3. 강건한 삼각측량과 재삼각측량[편집]

새 점을 만들 때 COLMAP은 트랙(같은 3차원 점을 본다고 주장하는 관측들의 집합) 안에서 두 개씩 뽑아 삼각측량하고, 다른 관측들이 그 결과에 동의하는지를 RANSAC으로 센다. 트랙 안에 오대응이 섞여 있어도 다수결이 이기는 구조다. 각도 검사와 양의 깊이 검사를 통과 못 하면 점을 만들지 않는다.

더 중요한 것이 재삼각측량(re-triangulation)이다. 초기에는 삼각측량 각이 작아서, 혹은 자세가 아직 부정확해서 버려졌던 관측이 있다. 카메라가 더 붙고 BA로 자세가 정련되고 나면 그 관측들은 이제 성공한다. COLMAP은 BA 직전직후 두 번 재삼각측량을 걸고, 모형이 더 이상 커지지 않을 때까지 이 사이클을 반복한다. 이 한 단계가 완성도에 미치는 영향이 커서, 긴 통로처럼 트랙이 잘 끊기는 데이터에서 특히 차이가 난다.

2.4. 번들 조정을 감당하는 법[편집]

번들 조정은 점진적 SfM에서 수백 번 반복 호출되는 가장 비싼 부품이다. COLMAP은 새 사진을 붙일 때마다 그 사진과 직접 연결된 이웃만 최적화하는 국소 BA를 돌리고, 모형이 일정 비율 이상 커졌을 때만 전역 BA를 돌린다. 전역 BA에서는 서로 거의 같은 것을 보는 중복 시점들을 군집으로 묶어 파라미터를 축약한다 — 관광지 사진처럼 같은 각도의 사진이 수백 장 있는 데이터에서 이 압축이 결정적이다.

선형대수 쪽 사정은 SfM·BA 공통이다. 야코비안의 희소행렬 구조를 이용해 슈어 보수로 점 변수를 소거하고 축소 카메라계만 푸는 표준 기법을 쓰며, 신뢰영역 레벤버그-마쿼트 방법에 코시·후버류 강건 손실을 얹는다. 내부적으로는 Ceres Solver를 쓴다. 자세한 것은 번들 조정 문서로 넘긴다.

3. 실제로 돌리는 순서[편집]

COLMAP은 GUI, CLI, C++ 라이브러리 세 얼굴을 갖는다. CLI로 보면 파이프라인이 명령 단위로 그대로 드러난다.

feature_extractor      # SIFT 추출 → database.db 에 저장
exhaustive_matcher     # (또는 sequential_matcher / vocab_tree_matcher)
mapper                 # 점진적 SfM → sparse/0/ (자세 + 희소 점군)
image_undistorter      # 왜곡 제거 + dense 작업공간 생성
patch_match_stereo     # 화소별 깊이·법선 맵
stereo_fusion          # 깊이맵 융합 → 밀집 점군
poisson_mesher         # (또는 delaunay_mesher) 메시

작은 데이터셋이면 automatic_reconstructor 한 방으로 전부 돈다. 상태는 전부 SQLite 파일 하나(database.db)에 들어가는데, 카메라·영상·키포인트·기술자·매칭·두 시점 기하가 각각 테이블이다. 매칭 결과가 DB에 남는다는 점이 실무적으로 아주 중요하다 — 매칭이 전체 시간의 대부분을 먹으므로, 파라미터를 바꿔 재구성을 다시 돌릴 때 특징 추출과 매칭을 건너뛰고 mapper부터 다시 돌리면 된다.

결과는 cameras / images / points3D 세 파일(바이너리 또는 텍스트)로 나온다. 각각 내부파라미터, 카메라 자세와 관측, 3차원 점과 트랙이다. 이 포맷이 사실상 업계 교환 표준이 되어서, 다른 도구들이 “COLMAP 포맷을 읽는다”고 광고하는 상황이 됐다.

매칭 모드 선택이 규모를 결정한다.

모드비교 쌍언제
exhaustive모든 쌍수백 장 이하
sequential인접 프레임 + 루프 검출동영상·순차 촬영
vocab_tree시각 단어로 상위 kk 개만수천 장 이상
spatialGNSS 좌표 근방드론·항공

카메라 모델도 명시적으로 고른다. SIMPLE_RADIAL(초점거리 하나 + 방사왜곡 하나)이 기본값이고, 어안이나 강한 왜곡이 있으면 OPENCV_FISHEYE 계열로 바꾼다. 같은 카메라로 찍은 사진이면 single_camera 옵션으로 내부파라미터를 공유시키는 것이 정확도에 크게 유리하다. 이 선택들이 카메라 보정과 맞물리는 지점이다.

3.1. 좌표 규약 — 자세 파일을 읽을 때 반드시 걸리는 곳[편집]

images 파일의 한 줄은 IMAGE_ID QW QX QY QZ TX TY TZ CAMERA_ID NAME 형식이고, 여기 담긴 (R,t)(R,\mathbf t)월드 → 카메라 변환이다. 즉 카메라의 월드 좌표는 t\mathbf t 가 아니라

c=Rt\mathbf c = -R^{\top}\mathbf t

이다. 사원수는 (qw,qx,qy,qz)(q_w,q_x,q_y,q_z) 순서로 실수부가 앞에 온다. 카메라 좌표계는 광축이 +Z+Z, 영상 yy 축이 아래 방향(+Y+Y)이다.

이 세 줄이 왜 중요하냐면, 다른 생태계의 규약이 전부 다르기 때문이다. 그래픽스 쪽(OpenGL 계열, 그리고 그 규약을 물려받은 신경 렌더링 코드 다수)은 카메라가 Z-Z 를 보고 yy 축이 위를 향한다. 그래서 COLMAP 자세를 그쪽으로 옮길 때는 카메라 → 월드로 뒤집고, yy·zz 축의 부호를 바꾸는 변환이 들어간다. 변환 스크립트를 잘못 쓰면 재구성이 뒤집히거나 거울상이 되는데, 증상이 “학습은 되는데 결과가 흐릿하다” 정도로만 나타나서 원인을 찾는 데 하루를 태우는 일이 흔하다. 자세 파일을 처음 다룰 때는 카메라 위치 몇 개를 직접 찍어 보고 촬영 궤적 모양이 말이 되는지 눈으로 확인하는 것이 가장 빠르다.

3.2. 재구성 말고 쓰는 법[편집]

COLMAP의 서브커맨드 중 파이프라인 바깥에서 더 자주 쓰이는 것들이 있다.

  • point_triangulator자세를 이미 알 때 삼각측량만 다시 한다. 다른 방법(GNSS·INS·기계적 리그)으로 얻은 자세에 COLMAP의 점군만 얹고 싶을 때 쓴다.
  • model_aligner — 재구성 결과를 지상기준점이나 GNSS 좌표에 유사변환으로 맞춘다. 임의 좌표계를 실제 좌표계로 바꾸는 단계가 이것이고, 여기서 나오는 잔차가 곧 포토그래메트리식 정확도 보고의 재료다.
  • model_converter — 바이너리와 텍스트, 그리고 다른 도구용 포맷 사이 변환.
  • model_merger / rig_bundle_adjuster — 조각난 모형 합치기, 고정된 상대 자세를 갖는 카메라 리그 구속 넣기.

4. MVS — PatchMatch와 화소별 뷰 선택[편집]

SfM이 끝나면 자세는 확정이고, 남은 것은 화소마다 깊이를 채우는 다중 시점 스테레오다. COLMAP의 MVS는 별도 논문(ECCV 2016)의 내용이며 핵심이 셋이다.

1) PatchMatch식 전파. 모든 깊이 후보를 다 뒤지는 대신, 각 화소에 깊이와 법선을 무작위로 초기화한 뒤 이웃의 값을 받아 보고 더 나으면 채택하는 전파를 반복한다. 이웃이 좋은 값을 찾으면 그 값이 영역 전체로 번져 나가는 구조라, 탐색 비용이 후보 수가 아니라 반복 횟수에 비례한다. PatchMatch 알고리즘의 발상을 스테레오에 옮긴 계열이고, 법선까지 추정하기 때문에 비스듬한 벽면에서 전면평행 가정이 만드는 계단 현상이 사라진다. 격자를 체스판처럼 두 색으로 나눠 번갈아 갱신하면 전파가 병렬화된다.

2) 화소별 소스 뷰 선택. 이 논문의 진짜 기여다. 기준 영상의 어떤 화소는 이웃 영상 A·B에서 잘 보이고, 바로 옆 화소는 가림 때문에 C·D에서만 보인다. 영상 단위로 “이 사진에는 저 사진들을 쓰겠다”를 고정하면 가림 경계에서 반드시 틀린다. COLMAP은 각 화소마다 어느 소스 영상이 유효한지를 잠재변수로 두고 깊이·법선과 함께 추정한다. 화소를 따라가며 뷰 유효성이 이어진다는 사전정보를 넣으면 이 잠재변수의 사슬이 은닉 마르코프 모형이 되고, 전방-후방 계산으로 다뤄진다.

3) 광도 일관성 + 기하 일관성. 비용 함수는 양방향 가중 정규화 상호상관(NCC)에 기하 일관성 항을 더한 것이다. 기하 일관성은 기준 영상의 화소를 이웃으로 투영했다가 그 이웃의 깊이로 되돌렸을 때 원래 자리로 돌아오는지를 본다 — 텍스처가 약한 면에서 광도 항만으로는 깊이가 헤매는 것을 잡아 준다.

마지막으로 깊이맵 융합이다. 모든 영상의 깊이·법선 맵을 3차원으로 올린 뒤, 여러 영상이 서로 지지하는 점만 남기고 평균한다. 지지 영상 수, 재투영 오차, 법선 각도 차이가 임계값으로 들어가며, 여기서 나온 밀집 점군을 메시 생성(들로네 기반 또는 푸아송)으로 넘기면 파이프라인이 끝난다.

실무 주의사항 하나. patch_match_stereo 는 GPU 연산이 사실상 필수이고 메모리를 많이 먹는다. 밀집 단계에서 터진다면 영상 최대 크기와 동시에 올리는 소스 영상 수를 먼저 줄이는 것이 정석이다.

5. 신경 렌더링 시대의 COLMAP[편집]

2020년 이후 COLMAP의 쓰임새가 하나 더 늘었다. 장면을 신경망 필드나 3차원 가우시안 집합으로 표현하는 방법들이 거의 전부 「정확한 카메라 자세」를 입력으로 요구하는데, 그 자세를 만드는 표준 도구가 COLMAP이다.

  • NeRF 계열 — 학습에 각 영상의 자세와 내부파라미터가 필요하다. 공개 데이터셋의 자세 파일이 COLMAP 출력을 변환한 것인 경우가 압도적이고, 자기 데이터로 돌리려면 첫 단계가 colmap 실행이다.
  • 3D 가우시안 스플래팅 — 자세뿐 아니라 희소 점군까지 쓴다. COLMAP이 뱉은 점들을 가우시안의 초기 위치로 삼는 것이 표준 구성이라, 점군이 빈약하면 학습 결과가 눈에 띄게 나빠진다. SfM 산출물의 “부산물”이던 희소 점군이 갑자기 1급 입력이 된 셈이다.

그래서 요즘 이 분야의 실패 보고는 렌더링 품질 문제로 시작해 SfM 문제로 끝나는 경우가 많다. “NeRF가 흐릿하게 나온다”의 원인이 신경망이 아니라 자세가 몇 화소 틀린 것인 경우가 흔하고, 자세를 학습 중에 함께 미세조정하는 기법들이 나온 것도 그래서다. 표현이 아무리 바뀌어도 자세를 만드는 문제는 여전히 SfM의 몫이라는 사실이 오히려 더 또렷해졌다.3

한편 COLMAP 자신도 정지해 있지 않다. 점진적 방식의 근본적 약점인 계산량을 겨냥해, 같은 매칭 DB를 그대로 받아 전역 방식으로 푸는 후속 구현이 2024년에 나왔다. 전역 SfM이 오래 패배해 온 이유였던 이동 평균화의 취약성을 다르게 다루어, 큰 장면에서 수십 배 빠르면서 정확도는 비슷한 수준을 보고했다. 「점진적이 무조건 강건하다」는 10년 묵은 상식이 다시 검토되는 중이다.

6. 실무에서 조심할 것[편집]

  • 재구성이 여러 조각으로 나왔다면 파라미터가 아니라 데이터 문제다. sparse/0, sparse/1 처럼 모형이 여러 개 나오는 것은 장면 그래프가 끊겼다는 뜻이고, 처방은 끊긴 지점을 잇는 사진을 더 찍는 것이다.
  • 매칭 모드를 먼저 정해라. 사진 2000장에 exhaustive_matcher 를 걸면 쌍이 200만 개다. 순차 촬영이면 sequential, 큰 뭉치면 vocab_tree 가 맞다. 이건 정확도 선택이 아니라 완료 여부 선택이다.
  • DB를 재활용해라. mapper 옵션을 바꿔 가며 실험할 때 특징 추출부터 다시 돌리는 것은 순수한 시간 낭비다.
  • 하늘·물·움직이는 사람은 마스킹해라. 정적 장면 가정 위반은 파라미터로 못 고친다. 마스크 한 장이 튜닝 열 번보다 낫다.
  • 자세가 나왔다고 스케일이 나온 것은 아니다. 출력 좌표계는 임의의 유사변환까지만 정해져 있다. 실제 치수가 필요하면 기준점이나 스케일바를 넣고 좌표계를 정의해야 하며, 그 절차가 곧 포토그래메트리가 하는 일이다. 「모형이 예뻐 보인다」와 「±2 cm를 보증한다」는 다른 산출물이다.
  • BA 잔차만 보고 안심하지 마라. 재투영 오차가 작은데 형상이 휘어 있는 경우가 있다. 잔차는 관측과의 일관성이지 실제 정확도가 아니며, 검사점으로 따로 재야 한다.

7. 관련 문서[편집]

8. Footnotes[편집]

  1. SfM 구현의 재현성 문제를 한마디로 요약하면 “논문의 알고리즘은 20줄인데 돌아가는 코드는 20만 줄”이다. 그 차이의 대부분이 임계값, 재시도, 예외 처리, 실패한 단계를 되돌리는 로직이다. COLMAP이 인용 수로 이긴 것이 아니라 깃 저장소로 이겼다는 평가가 나오는 이유다.

  2. 워터마크 문제는 처음 들으면 우스운데, 실제로는 인터넷 사진 재구성에서 가장 잘 알려진 재난 중 하나였다. 같은 사진 공유 사이트에서 긁은 사진 수천 장이 전부 우하단에 같은 로고를 달고 있으면, 기하 검증 입장에서 그 로고는 “모든 사진에서 완벽하게 매칭되는 평면 패턴”이다. 결과적으로 로마와 파리가 같은 건물로 융합될 수도 있다는 뜻이다.

  3. 그래서 요즘 신경 렌더링 논문의 실험 절에는 “COLMAP 자세를 사용했다”가 거의 상수처럼 등장한다. 재미있는 역전도 일어났다 — 렌더링 품질이 자세 오차에 워낙 민감하다 보니, 렌더링 손실로 자세를 거꾸로 미세조정하는 연구가 나오고 그 결과가 SfM 정련보다 나은 경우도 보고된다. 자세를 만들어 준 쪽이 자세를 고쳐 받는 구도다.