MetaView는 단일 이미지 + target 카메라 pose로 novel view를 만드는 diffusion 모델이다 (Qwen-Image-Edit MM-DiT 백본 + DA3 implicit geometry prior + PRoPE metric scale anchoring). 학습 데이터는 scene-level orbit NVS(DL3DV-10K / RealEstate10K / Sekai)로, 카메라가 씬 중심 구면 위를 도는 움직임이다.
질문: DROID의 exo(고정 외부) 카메라 프레임을 넣고 실제 exo→wrist 상대 pose를 주면 wrist 뷰가 나오는가? 된다면 로봇 데이터셋에서 wrist 뷰를 합성으로 늘릴 수 있어 가치가 크다.
~/Dataset/droid_full_processed/ (3162 에피소드). 각 에피소드에 exo/wrist MP4(1280×720, 49프레임)와 pose npy.
ego_camera_pose.npy (6,)는 정적 exo 카메라, wrist_camera_poses.npy (T,6)는 per-frame wrist다. DROID-EgoX 전처리의 "ego = wrist" 관례와 반대. 파일 shape(단일 vs per-frame)으로 교차 확인했다.포즈 규약의 진실 소스는 ~/Dataset/droid_align/src/data/io.py:
MetaView의 viewmats는 [target_w2c, source_w2c]이고 source는 항상 단위행렬(world = 소스 카메라 프레임). 따라서 orbit 파라미터를 버리고 target 자리에 실제 상대 pose를 넣으면 된다.
infer_droid.py는 DA3 prior를 프레임별로 먼저 뽑고 DiT는 1회만 로드해 (frame, α) 조합에 재사용한다. 출력은 3-panel [exo | 생성 | 실제 wrist GT] — src/metric.py가 요구하는 포맷이라 정량 평가로 바로 넘어갈 수 있다.
scale_se3(T, α)는 회전을 axis-angle 크기로, 이동을 선형으로 스케일해 identity(α=0)→실제 pose(α=1)를 보간한다. α=1 단독 실행은 실패 시 "분포 밖이라 망함" 외에 정보가 없지만, sweep은 붕괴 지점을 준다.
2번이 핵심이다. orbit이 멀쩡한데 pose 경로가 깨지면 pose 문제, 둘 다 깨지면 도메인 문제로 감별된다.
| 항목 | 범위 | 해석 |
|---|---|---|
| 이동량 | 0.44 ~ 0.84 m | 씬 안쪽으로 파고듦 |
| 회전각 | 103 ~ 165° | wrist가 그리퍼를 내려다보느라 exo와 거의 마주봄. orbit 학습 범위(±60° 수준)의 약 3배 |
α 보간 (frame 24):
| α | 이동 | 회전 |
|---|---|---|
| 0.25 | 0.210 m | 41.2° |
| 0.50 | 0.420 m | 82.4° |
| 1.00 | 0.841 m | 164.7° |
AUTOLab+44bb9c36+2023-11-23-15h-16m-18s, frame 24
| 조건 | PSNR | SSIM | Notes |
|---|---|---|---|
| α=0.25 | 10.07 | 0.280 | baseline보다 낮음 |
| α=1.0 | 9.62 | 0.308 | baseline보다 0.5dB 낮음 |
| exo 원본 그대로 (baseline) | 10.14 | 0.302 | 아무것도 안 한 것이 제일 낫다 |
1. 파이프라인은 완전히 동작한다. orbit baseline이 DROID 이미지에서 깨끗하게 나온 것이 결정적이다. 실패는 도메인(로봇 실내 씬) 문제도, 구현 버그도 아니고 pose가 학습 분포 밖이라서다. 이 감별을 위해 orbit baseline을 넣은 것이 설계상 제일 잘한 판단이었다.
2. 모델은 우아하게 실패한다. α=1.0에서 노이즈나 아티팩트가 아니라 "그럴듯하지만 틀린" 이미지를 낸다. 즉 극단적 pose를 받으면 조건을 무시하고 생성 prior로 도망간다. NVS로는 쓸모없지만, 백본이 로봇 씬을 이해는 하고 있다는 뜻이라 finetune 가능성의 신호다.
3. 165° 회전이 진짜 장벽으로 보인다. α=0.25(41°)에서 구조가 살아있고 α=1.0(165°)에서 무너지므로, 붕괴는 이동량보다 회전각에 걸려 있을 가능성이 높다. (미검증 가설)
4. zero-shot으로 wrist 뷰를 공짜로 얻는 길은 닫혔다. 쓰려면 finetune이 필요하다.
intrinsic 불일치 (가장 중요). droid_full_processed에 카메라 intrinsic이 없어 DA3가 exo에서 추정한 K를 target에도 그대로 썼다. 실제 wrist ZED는 FOV가 다르므로 오차 요인이다. raw ~/Dataset/droid/zed_calib/SN*.conf에 실제 값이 있다. α=1.0 실패의 일부가 여기서 왔을 수 있어, 결론을 확정하기 전에 배제해야 한다.
표본이 1 에피소드 1 프레임. 3-panel 이미지 3장이 전부다. 일반화 주장 불가.
PSNR/SSIM이 둔감. baseline이 10dB라 바닥에 깔려 있다. src/metric.py의 DMD나 LPIPS가 "기하가 맞아가는가"를 훨씬 잘 잡을 것. metric env 미구축.
α=0.5 미실행 (스모크에서 0.25/1.0만).
1. 실제 wrist intrinsic 물려서 α=1.0 재실행 — 가장 싼 교란요인 제거
2. α ∈ {0.25, 0.4, 0.5, 0.6, 0.75, 1.0} 조밀 sweep × 에피소드 10개 → 붕괴 지점을 회전각의 함수로 특정. 가설: 60~90° 사이에서 무너진다
3. 회전/이동 분리 실험 — 회전만 α, 이동은 1.0 (및 반대). Takeaway 3 검증
4. metric env 구축 후 DMD/LPIPS로 재측정
5. 그 다음에야 finetune 판단. exo→wrist pair는 3162 ep × 49 frame ≈ 15만 쌍으로 충분하다
README / pyproject.toml이 실제 의존성과 어긋난다:
| 문제 | 조치 |
|---|---|
README clone Depth-Anything-3.git → cd DepthAnything3 (디렉토리명 불일치). inference.py:10 import는 DepthAnything3 | clone 대상을 DepthAnything3로 지정 |
README 레이아웃은 checkpoint-best.safetensors, HF 실제 파일은 model-2500-best.safetensors | 실제 이름 사용 |
opencv-python(GUI 빌드)이 헤드리스 노드에서 libGL.so.1로 죽음 | opencv-python-headless==4.11.0.86 |
위 설치가 numpy를 2.2.6으로 승격, DA3는 numpy<2 요구 | numpy==1.26.4 핀 |
src/lora.py:9가 쓰는 diffusers가 README·pyproject 어디에도 없음 | diffusers==0.39.0 설치 |
env: ~/conda_envs/envs/metaview (python 3.10, torch 2.13.0+cu130). 추론 속도 40 step / 30초.
1샘플 스모크만으로 결론을 낸 게 성급했다. 두 가지를 검증했다: (a) 내 pose가 맞는가 (w2c/c2w 뒤집기 버그는 "그럴듯하지만 틀린" 이미지라는 동일 증상을 낸다), (b) 1샘플로 일반화 불가.
DA3 metric depth로 exo를 unproject → 같은 exo→wrist 행렬로 변환 → 재투영(forward splat + z-buffer). 모델 개입 없음.
| percentile | rotation | translation |
|---|---|---|
| p1 | 58.4° | 0.23 m |
| p25 | 128.5° | 0.47 m |
| median | 147.2° | 0.60 m |
| p75 | 162.0° | 0.73 m |
난이도 3구간(easy <60° / mid 90° / hard 150°) × 3, 랩 분산. LPIPS(vgg) 추가 — PSNR/SSIM이 10dB 바닥에서 포화돼 둔감했으므로.
| band | rot | trans | ΔPSNR | ΔLPIPS |
|---|---|---|---|---|
| easy | 10.3° | 0.73m | +0.80 | +0.001 |
| easy | 14.4° | 0.68m | +0.27 | −0.006 |
| easy | 16.5° | 0.84m | +0.11 | +0.030 |
| mid | 90.0° | 0.49m | +0.81 | −0.001 |
| mid | 90.1° | 0.60m | −0.20 | +0.018 |
| mid | 90.1° | 0.40m | +2.51 | −0.042 |
| hard | 150° | 0.34m | +1.02 | −0.013 |
| hard | 150° | 0.52m | −0.39 | +0.037 |
| hard | 150° | 0.52m | +1.34 | −0.023 |
Δ = 생성 − exo원본 baseline. ΔPSNR>0 좋음, ΔLPIPS<0 좋음.


정정 1 — "이득 0"은 1샘플 과잉단정이었다. 9샘플에서 PSNR 7/9로 baseline 이김(+0.70dB, t≈2.5). 단 LPIPS 무승부(5/9, 값 0.61~0.81로 매우 높음) — 지각적 개선은 없고 PSNR 이득은 전역 밝기/색 통계 수준.
정정 2 — "회전이 장벽" 가설이 데이터와 반대. 난이도 구간이 성적과 무상관(ρ=+0.16). 상관은 이동량에서 나옴(ρ=−0.58). 최고 +2.51dB가 이동 0.40m(최단), 최악이 0.84m.
1. 이동량 상관을 n=30~50으로 검증 (최우선). 유의하면 "PRoPE metric anchoring이 >0.5m 이동에서 실패" 확정 → finetune 설계 직결. 회전/이동 α 독립 스케일로 교차확인
2. wrist intrinsic 보정은 우선순위 하락 — 모델이 각도 무관하게 pose를 약하게 쓴다면 intrinsic으론 안 고쳐짐
3. metric env로 DMD 측정 (기하 정합엔 LPIPS/DMD가 PSNR보다 적합)
4. finetune 판단: exo→wrist 약 15만 쌍. 단 median 147°는 orbit prior와 너무 멀어 LoRA 이상 개입 필요할 수 있음
큰 한 방(0.84m/165°)을 모델이 무시하니, 궤적을 잘게 쪼개 비디오로 붙이면 다를까? 한 에피소드 49프레임을 각 프레임의 실제 pose(t)로 생성 — exo는 정적이나 씬(팔/물체)이 매 프레임 변하고 wrist pose도 변하므로 전 프레임에 실제 wrist GT가 존재한다.
갈래 A(독립 생성 stitch)는 correctness를 못 고친다 — 확정. 시간축으로 매끄럽게 이어붙여도 각 프레임 pose 순응도가 그대로. 결과는 "실제 wrist와 다른, 그럴듯한 대체 뷰의 비디오". 정지 9장 + 연속 49프레임 두 방식이 일치하므로 "모델이 pose를 각도 무관하게 약하게 반영"이라는 진단은 이제 단단하다.
correctness를 고칠 유일한 후보는 갈래 B(autoregressive chaining)뿐 — 작은 스텝 생성 → 생성물을 다음 source로 재투입. 단 (a)10°도 안 따라가 작은 스텝 이점 약함 (b)DA3를 생성 프레임에서 재추출해 오차 복리누적. 예측은 B도 실패. zero-shot의 마지막 시도.