optimize_pose_graph — 3D pose_graph op

• 데이터 종류: pose → table

• 호출: import fullseye as fs; fs.ledger.optimize_pose_graph(poses_init, edges, fix_first=True, max_iter=200)(구현을 직접 호출하려면 import pose_graph; pose_graph.optimize_pose_graph(poses_init, edges, fix_first=True, max_iter=200), 원장에서 가져오려면 ops3d.get("optimize_pose_graph"))

사용법

상대 자세 제약 + 루프 클로저로부터 전역 자세를 최적화. → dict{poses, rmse, cost}.

poses_init (N,6)=[rvec|t] 의 초기 추정(드리프트 있음)을, edges 의 상대 자세 제약을 만족하도록 최적화한다. fix_first=True 로 선두 노드를 고정해 gauge 를 제거한다.

• edges: (i, j, rvec_ij, t_ij[, w_rot, w_trans]) 의 리스트. (rvec_ij, t_ij) 는 "i 에서본 j" = T_i⁻¹ ∘ T_j 의 측정값(relative_pose 와 같은 규약). 오도메트리 (i, i+1) 와루프 폐합(떨어진 i, j)을 같은 형태로 섞어도 된다. 가중치는 잔차에 sqrt(w) 를 곱한다(생략 시 1).

• 각 에지의 잔차는 measured⁻¹ ∘ predicted 를 회전 벡터 + 병진의 6 차원으로 한 것으로, scipy.optimize.least_squares(method="lm") 로 최소화한다(max_nfev = max_iter × 파라미터 수).

• 반환값: poses (N,6)(fix_first 이면 선두는 초기값 그대로), rmse = mean_edge_error(poses, edges), cost = 최종 비용(잔차 2 제곱합의 1/2).

fail-closed: 노드 수 < 2, 에지 0 개, 에지의 첨자가 [0, N) 을 벗어나는(음의 첨자의 조용한되감기도 거부) 경우는 ValueError. fix_first=False 로 하면 gauge 가 남아 해는 유일하지 않다(LM 은 초기값 근처의 1 개를 반환한다). 회전은 rad, 병진은 좌표의 단위이며, 둘을 같은 잔차 벡터에늘어놓으므로 단위가 크게 다를 때는 가중치로 맞춘다. 3D 점도 관측 화소도 쓰지 않는다(그것들을 포함해최적화하는 것은 bundle_adjust).

참고(샘플 데이터·문헌)

• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.

• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.

실행 가능한 예제(이 연산자를 실제로 호출하는 검증된 샘플)

• pose_graph_slam — py -3.11 examples_3d/pose_graph_slam.py

타입이 이어지는 다음 연산자(table 를 입력으로 받는 것)

fuse_to_voxel · mesh_select_lod

같은 카테고리(pose_graph)

relative_pose · mean_edge_error


*Provenance: pose_graph.py — 3D 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.