register_fpfh — 3D 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"))

用法

用 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 → 以全點 fitness (將 src 全部點變換後,其 dst 最近鄰落在閾值內的比例)評分。只用對應(~100點) 評分容易固著於錯誤位姿,因此以全點 fitness 使其穩健。

6) 以最佳位姿的對應內點重新擬合。

參數:

src (N,3), dst (M,3): 要對位的 2 個點雲(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/None 時停用(維持原始點雲。獨立取樣時不建議)。

normal_k (int): 法線估計的鄰域數。

feature_k (int): FPFH 的鄰域數(越大描述子越穩定、越有鑑別力。建議 60 左右)。

n_bins (int): 每 1 個特徵的直方圖分箱數(描述子維數 = 3*n_bins)。

ransac_iters (int): RANSAC 迭代次數。

inlier_thr (float or None): 內點距離閾值。None 時為(降取樣後)解析度×3。

edge_sim (float): 三元組邊長比的容許度(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"(全點 fitness=restart 選擇的指標), "rmse"(內點 RMSE),

"inlier_thr", "src_corr","dst_corr"(對應 index)}。

注意(honest): 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 執行緒、快取、記憶體配置

參考(範例資料、文獻)

• 範例資料目錄(下載 URL / 授權) —— 2-D 用 skimage.data(BSD/公有領域)加合成圖,3-D 給出真實資料源(Stanford/PDS 等)的下載 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 運算子登記表。本條目由 tools/opdocs.py md 自動產生(請勿手動編輯)。*

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