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.