icp_point2point_3d — 3D refine op

• 데이터 종류: points × points → pose

• 호출: import fullseye as fs; fs.ledger.icp_point2point_3d(src, dst, iters=50, init_R=None, init_t=None, tol=1e-06, max_corr_dist=None, trim_ratio=None, device='cpu', reproducible=False)(구현을 직접 호출하려면 import match3d; match3d.icp_point2point_3d(src, dst, iters=50, init_R=None, init_t=None, tol=1e-06, max_corr_dist=None, trim_ratio=None, device='cpu', reproducible=False), 원장에서 가져오려면 ops3d.get("icp_point2point_3d"))

사용법

점군을 point-to-point ICP(Kabsch/SVD)로 정련합니다.

대략적 매치 추정(정수NCC / Fourier-Mellin±3° / Hough±0.5voxel)으로 얻은초기 자세 (init_R, init_t) 를 출발점으로, src 측 점군을 dst 측 점군에 강체 변환으로위치 맞춤한다. 각 반복에서 최근접 대응(cKDTree)을 다시 만들고, Kabsch 알고리즘(SVD)으로 상대 회전·병진을 구해 누적함으로써, 대응이 알려져 있지 않아도서브복셀 정밀도로 수렴시킨다.

부분 겹침·이상값에는 Trimmed ICP(거리가 작은 대응만 채택)와절대 거리 게이트(max_corr_dist)로 대처한다. 최종 RMSE 는 실제로 채택한대응(인라이어) 위에서 평가하므로, 부분 관측에서도 자세 품질을 올바르게 반영한다.

인수:

src: (N,3) 이동 측 점군(torch.Tensor 또는 numpy.ndarray).

dst: (M,3) 고정 측(참조) 점군.

iters: 최대 반복 횟수.

init_R: (3,3) 초기 회전. None 이면 단위 행렬.

init_t: (3,) 초기 병진. None 이면 영벡터.

tol: RMSE 의 상대 개선이 이 값 아래로 떨어지면 수렴으로 보고 종료.

max_corr_dist: 이 거리를 넘는 대응을 이상값으로 기각(None 이면 비활성).

trim_ratio: 0<r<=1. 각 반복에서 최근접 거리가 작은 상위 r 비율의 대응만

채택하는 Trimmed ICP. 부분 겹침(겹침률 r)에 유효. None 이면 비활성.

device: torch 디바이스("cpu" 등). SVD 를 이 디바이스에서 푼다.

reproducible: True 이면 점의 순서·BLAS 스레드 수에 의존하지 않는 축약으로 한다(기본값 False = 종래대로).

평균은 math.fsum, 상호 공분산 H 는 ozakimm(Ozaki 스킴), 자세 적용은 요소별 연산, RMSE 도 math.fsum.

src 점의 순서를 바꿔도 R·t·rmse 가 비트 단위로 같다(같은 계산기·같은 LAPACK 위에서). trim_ratio 의 경계에서

거리가 정확히 동점인 점은 순서에 따라 선택이 달라질 수 있다. 20 만 점에서 1 반복당 0.7 ms 가 170 ms 정도가 된다.

반환값:

R: (3,3) 회전. dst ~= src @ R.T + t 를 만족한다. torch 가 있는 환경에서는 torch.Tensor, 없으면 같은 값의 numpy.ndarray(2026-09-07 에

본체를 numpy 화했을 때도, 호환을 위해 타입은 그대로 두었다).

★같은 족의 icp_point2plane 은 항상 numpy 를 반환한다 —— 족 안에서

타입이 맞지 않으므로, 하류에서는 np.asarray(R) 를 거치는 것이 안전

(어느 쪽이든 동작한다. 파괴적 변경을 피하려고 이 불일치를 남겨 두었다).

t: (3,) 병진(R 과 같은 타입).

info: dict. "rmse"(채택 대응 위의 최종RMSE), "iters"(실제 반복 수),

"converged"(bool), "inliers"(채택 대응 수), "rmse_history"(list).

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

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

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

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

• gicp_register — py -3.11 examples_3d/gicp_register.py

• itokawa_self_register — py -3.11 examples_3d/itokawa_self_register.py

• itokawa_shape_match — py -3.11 examples_3d/itokawa_shape_match.py

• partial_overlap_icp — py -3.11 examples_3d/partial_overlap_icp.py

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

fuse_to_voxel · pose_error · bundle_adjust · mean_reprojection_error · optimize_pose_graph · relative_pose · mean_edge_error · rotation_translation_error

같은 카테고리(refine)

refine_peak_newton · refine_translation_lk · refine_lm · refine_rotation_z · icp_point2plane


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

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