feature_register op• 데이터 종류: points × points → pose
• 호출: import fullseye as fs; fs.ledger.register_fpfh(src, dst, src_normals=None, dst_normals=None, voxel_size=None, normal_k=16, feature_k=60, n_bins=11, ransac_iters=8000, inlier_thr=None, edge_sim=0.9, mutual=True, ratio=0.95, seed=0, device='cpu')(구현을 직접 호출하려면 import feat_fpfh; feat_fpfh.register_fpfh(src, dst, src_normals=None, dst_normals=None, voxel_size=None, normal_k=16, feature_k=60, n_bins=11, ransac_iters=8000, inlier_thr=None, edge_sim=0.9, mutual=True, ratio=0.95, seed=0, device='cpu'), 원장에서 가져오려면 ops3d.get("register_fpfh"))
• GPU: 없음(CPU 참조 구현만)
FPFH 기술자 + RANSAC 으로 초기 추정 없이 강체 정합 (R,t) 를 추정합니다.
2D Harris/SIFT에 해당하는 희소한 feature 성냥의 3D 버전. 양쪽 구름을 FPFH 기술자로 나타내고, 디스크립터 공간의 가장 가까운 이웃에서 상호 작용 (상호 최근 이웃 + Lowe ratio로 필터링), RANSAC에서이상치에 견고한 강체 자세를 풀어준다. 밀매치(NCC/Hough)나 PCA와 달리 대회전(50-70°) +병진 + 부분 겹쳐도 초기 추정 없이 자세를 낼 수 있는 것이 가치. 얻은 (R, t)는 ICP의 초기 값입니다. (coarse init)로 전달하면 표면 정밀도까지 조인다 (dst ≈ src @ R.T + t의 ICP 관습).
파이프라인:
1) voxel 다운 샘플(독립 샘플링 2 구름의 근방을 공통 해상도에 맞춘다. FPFH의 대응 정답률을 크게 좌우하는 필수 전처리).
2) 법선 추정 (국소 PCA). src_normals/dst_normals 를 건네주면 그것을 사용한다.
3) FPFH 디스크립터 (SPFH → 거리 가중치 합성).
4) 디스크립터 NN 매치(mutual + ratio).
5) RANSAC: 3점 샘플 → edge-length 매칭 프리필터 → Kabsch → 전점 피트니스 (src 전체 점을 변환하고 dst 최근 이웃이 임계 값 내에 들어가는 비율)로 채점. 대응(~100점)만의채점은 오자세에 고착하기 쉽기 때문에, 전점 피트니스로 완건화한다.
6) 최상의 자세 대응 인라이어로 재핏.
인수:
src (N,3), dst (M,3): 정렬할 두 점군(numpy/torch).
src_normals, dst_normals ((N,3)/(M,3) or None): 사전 법선. None이면 내부 추정
(단 voxel_size>0일 때는 좌표가 바뀌므로 항상 재추정).
voxel_size (float or None): 다운 샘플 변장. None으로 dst 해상도×2.5를 자동 채용.
0으로 무효화(생점군 그대로.독립 샘플링에서는 비추천).
normal_k (int): 법선 추정의 근방수.
feature_k (int): FPFH의 근방수(클수록 기술자가 안정·식별적.60 전후를 추천).
n_bins (int): 피쳐당 히스토그램 빈 수(설명자 차원 = 3*n_bins).
ransac_iters (int): RANSAC 반복 수.
inlier_thr (float or None): 인라이어 거리 임계치. None (다운 샘플 후) 해상도 x3.
edge_sim (float): 3조의 변장비의 허용(0<edge_sim<=1, 1에 가까울수록 엄격).
mutual (bool): 상호 최근 이웃 필터. ratio (float or None): Lowe ratio.
seed (int): RANSAC 난수종(restart 시에 바꾼다). device (str): 반환값 텐서의 device.
반환값:
R (3,3) torch.Tensor(device 상단), t (3,) torch.Tensor,
info dict: {"n_corr"(대응 번호), "inliers"(인라이어 수), "inlier_ratio",
"fitness"(전점 피트니스 = restart 선택 지표), "rmse"(인라이어 RMSE),
"inlier_thr", "src_corr", "dst_corr"(대응 index)}.
주의 : FPFH는 coarse registration이며 독립 샘플링 + 노이즈 + 부분 중첩
어려운 조건에서는 회전 오차가 몇도 남는다 (실측 : 62 ° 회전 · 중첩 ~ 64 % · 노이즈 0.5 × 해상도 RANSAC 후 중앙값 ~4.4°, ~90%가 <8°, 나머지 ~10%는 8-9°의 경계. ICP로 조이면 100% 가 <8°·중앙값 ~0.5°). 노이즈가 점 간격(해상도) 수준 이상이 되면 법선·각 특징이무너짐 기술자가 식별력을 잃는다(실측: 노이즈 ≥1.0×해상도로 성공률이 저하). RANSAC는 난택그러므로 실제 운용에서는 몇 번 restart 해 info["fitness"] 최대의 결과를 취하면 좋다.
• blas_threads_and_memory — 행렬 분해가 느린 이유 — BLAS 스레드·캐시·메모리 배치
• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.
• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.
• feature_register — py -3.11 examples_3d/feature_register.py
pose 를 입력으로 받는 것)fuse_to_voxel · pose_error · bundle_adjust · mean_reprojection_error · optimize_pose_graph · relative_pose · mean_edge_error · rotation_translation_error
feature_register)harris3d_keypoints · iss_keypoints · compute_fpfh · shot_descriptor · register_spin · register_shot
*Provenance: feat_fpfh.py — 3D 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.