영상에서 3D를 생성해 보기: VGGT와 VGGT-SLAM을 사용한 실험
요약
본 글은 LiDAR 점군 데이터 없이 카메라 영상(RGB 이미지)만으로 3D 공간을 복원하는 방법을 다룹니다. VGGT와 VGGT-SLAM이라는 모델을 사용하여 깊이 추정 및 카메라 위치를 출력하고, 이를 시각화하는 과정을 소개합니다.
핵심 포인트
- VGGT는 RGB 이미지에서 깊이, 3D 점, 카메라 파라미터를 추정하는 모델입니다.
- 점군 데이터 없이 영상만으로 3D 복원(Structure from Motion)을 시도했습니다.
- VGGT-SLAM은 지도 구축과 카메라 궤적 추정을 위해 VGGT를 활용합니다.
- 실험 결과는 구현 구성 및 시각화에 초점을 맞추었으며, 공개 샘플을 사용했습니다.
점군 데이터를 입력하지 않고 영상에서 3D 복원이 가능한가
평소에는 영상에서 물체를 감지하거나 움직임을 추적하는 처리를 만들고 있습니다. 그 연장선상에서 궁금했던 것은, 'LiDAR 등으로 측정된 점군을 입력하지 않고 카메라 영상만으로 공간을 3D로 만들 수 있는가' 하는 것이었습니다.
이번에 사용한 입력은 RGB 이미지입니다. 깊이(depth)나 카메라의 위치를 이미지에서 추정하고, 그 결과를 점군(point cloud) 형태로 시각화합니다. 점군은 입력으로 준비하는 것이 아니라, 복원의 출력물로 취급됩니다.
이에 따라, VGGT와 VGGT-SLAM을 사용한 3D 복원을 시도했습니다. 영상에서 이미지를 추출하고, 점군 및 카메라 위치를 출력하여 브라우저에서 확인하는 과정까지의 메모입니다.
이번에는 엄밀한 정밀도 비교보다는, 구현된 구성과 시각화 부분을 소개하는 데 초점을 맞추었습니다. 이전 실험에 사용했던 영상을 대신하여, 기사용으로는 공개 샘플을 이용해 VGGT를 실행한 결과를 게재합니다. VGGT-SLAM의 경우, 이전에 시도했던 구성과 추가된 표시 처리 과정을 소개하겠습니다.
시도한 리포지토리
사용된 것은 다음 두 가지입니다.
VGGT는 이미지에서 깊이(depth)나 3D 점, 카메라 파라미터 등을 추정하는 모델입니다. VGGT-SLAM은 이를 활용하여 지도 구축과 카메라 궤적 추정을 다룹니다. 자세한 내용은 각 공식 README에 설명되어 있습니다.
직접 확인한 코드 커밋은, VGGT가 a288dd0이고,
VGGT-SLAM이 35327ac입니다. VGGT-SLAM의 README는 2.0 버전입니다. 아래 내용은 이 로컬 구성에 기반합니다.
먼저 영상을 이미지 배열로 만들기
먼저, 영상에서 입력 프레임을 추출합니다.
VGGT용으로는 시간 범위와 매수를 지정하여 대표 프레임을 선택하는 Python 스크립트를 추가했습니다. 단순한 등간격 추출 외에도, 구간 내 후보들 중 선명도(sharpness), 밝기(brightness), 대비(contrast)를 보고 선택하는 방식도 준비되어 있습니다.
다만, 이는 간단한 선택 규칙일 뿐입니다. 선명한 이미지를 고른다고 해서 3D 복원에 필요한 시점의 중첩이 보장되는 것은 아닙니다.
VGGT-SLAM에 전달할 이미지 배열은 FFmpeg으로도 만들 수 있습니다. 예를 들어, 5 fps로 추출하려면 다음과 같습니다.
mkdir -p frames
ffmpeg -i input.mp4 -vf
시간은 1회 실행에 한정되며, 모델 로드/읽기/전처리/표현을 포함하지 않습니다. 재현된 것은 VGGT의 공개 샘플 추론이며, VGGT-SLAM과의 성능 비교는 진행되지 않았습니다.
## 다이어그램 및 실행 결과 이미지
d이어그램과 공개 샘플로 VGGT를 실행한 결과를 모아서 게재합니다. 입력 이미지의 출처는 VGGT 공식 리포지토리의 LLFF fern 샘플입니다. 깊이는 공통 색 범위로 표시하며, 포인트 클라우드 이미지의 분홍색 점은 추정 카메라 위치를 나타냅니다. 실행 결과는 VGGT의 것이며, VGGT-SLAM의 출력물이 아닙니다.




## VGGT-SLAM: 이미지 시퀀스에서 지도와 궤적 처리하기
다음으로, VGGT-SLAM도 시험해 보았습니다.
이미지 시퀀스를 전달하여 Viser로 표시하는 진입점은 현재 환경에서는 다음 명령어입니다. 환경 구축은 공식 README를 참조해 주십시오.
python main.py
--image_folder frames
--max_loops 1
...
여기서는 공간의 형태뿐만 아니라, 촬영된 카메라가 어떻게 이동했다고 추정되는지를 볼 수 있습니다.
포인트 클라우드만 보는 것보다, 카메라의 위치나 방향도 함께 표시하는 것이 '이 부분은 어떤 시점에서 보였는지'를 따라가기 쉽습니다.
## 브라우저에서 볼 수 있도록 처리
시험을 하면서 추가한 것이 브라우저용 시각화 처리입니다.
VGGT 예측에는 프레임과 포인트 클라우드를 대응시키는 시간 순서 뷰어를 준비했습니다. 표시할 점의 수를 줄여, 원본 프레임이나 깊이 표시와 함께 확인할 수 있도록 한 것입니다.
VGGT-SLAM 쪽에는 저장된 포인트 클라우드를 WebGL로 표시하는 처리를 추가했습니다. 점의 XYZ 좌표와 색을 바이너리로 모아 브라우저에 읽히게 하는 구성입니다.
이 처리에서는 1점을 다음 16바이트로 저장합니다.
| 내용 | 타입 | 크기 |
|---|---|---|
| XYZ 좌표 | float32 × 3 | 12바이트 |
| RGBA | uint8 × 4 | 4바이트 |
1점 분을 쓰기하는 부분의 간략 예시
import struct
record = struct.pack(
...
3D 복원을 작동시키는 부분 외에, 결과를 회전/확대하여 확인할 수 있는 출입구를 만드는 것도 이번 시제품의 일부였습니다.
## 복원 결과를 볼 때 확인하고 싶은 것
겉보기에는 입체감이 있어도, 측정에 사용할 수 있는지는 별도의 평가가 필요합니다. 다음에 비교한다면, 다음을 확인하고 싶습니다.
- 프레임 매수나 추출 간격을 바꿨을 때, 형태와 카메라 궤적이 어떻게 변하는지
- 움직이는 차량이나 인물이 찍힌 장면에서, 포인트 클라우드에 어떤 영향이 발생하는지
- 신뢰도로 점을 제외했을 때, 노이즈와 필요한 형태가 어떻게 변하는지
- 거리를 다룰 경우, 알려진 치수와 대조하여 스케일을 확인할 수 있는지
이번 시제품에서는, 비디오를 이미지 시퀀스로 만들어 모델에 전달하고, 포인트 클라우드와 카메라 정보를 브라우저에서 확인하는 처리를 연결했습니다.
영상을 '무엇이 찍혔는지'에서 '어떤 공간이 찍혔는지'라는 관점에서 다룰 수 있는 것이 이 주제의 흥미로운 부분입니다. 다음에는 같은 입력에 대해 프레임 선택 방식을 바꿔서, 복원 결과의 차이를 나란히 비교해 보고 싶습니다.
### 토론 (Discussion)

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기