m3c2_distance — 3D metrics op

Datenarten: points × pointssignal

Aufruf: import fullseye as fs; fs.ledger.m3c2_distance(a, b, cores, normals, radius, max_depth=None, min_points=4) (die Implementierung direkt: import metrics3d; metrics3d.m3c2_distance(a, b, cores, normals, radius, max_depth=None, min_points=4); aus dem Register: ops3d.get("m3c2_distance"))

Rückgabewert über das Register: fullseye.ledger.m3c2_distance(...) liefert **nur den Wert des deklarierten Out-Typs signal** (die zugrunde liegende Funktion gibt zusätzlich Hilfsinformationen zurück). Wird das Verworfene gebraucht, nutze fullseye.ledger.m3c2_distance.raw(...) oder rufe metrics3d.m3c2_distance direkt auf.

Verwendung

> Für diesen Operator gibt es noch keine Übersetzung. Es folgt der Originaltext unverändert.

2 時点の点群の差を法線方向に測る(M3C2)。→ `(distance, lod)` の 2 つ。

最近傍距離(chamfer / C2C)は「いちばん近い点までの距離」なので、**傾いた面では

面に沿ったずれまで距離として数えてしまう**。地形・構造物の変化検出では、それが

「測り直しただけで検出される偽の変化」の主因になる(poc_structure_4d_deterioration

の実測: 劣化ゼロで測り返しただけで C2C の中央値 21.07 mm、法線方向なら 0.55 mm)。

M3C2(Lague 2013)は core 点ごとに **法線 `n を軸とする円筒**(半径 radius`、

長さ `max_depth)で両方の雲を切り取り、各点を n` に射影した平均の差を返す。

向きは `n` の指す側が正 —— 符号がそのまま「増えた / 減った」になる。

Args:

a: 時点 1 の点群 `(Na,3)`。

b: 時点 2 の点群 `(Nb,3)`。

cores: 測る場所 `(M,3)`(a の部分集合でも、別に置いた格子でもよい)。

normals: core ごとの法線 `(M,3)`(未正規化でよい。符号が結果の符号を決める)。

radius: 円筒の半径(core 周りで平均する範囲。面の粗さより大きく、測りたい

構造より小さく取る)。

max_depth: 円筒の長さの半分。`None` なら軸方向を制限しない。

min_points: 片側にこの数だけ点が無い core は `nan` を返す(既定 4)。

Returns:

`(distance, lod): どちらも (M,) float64。distance` は法線方向の

符号つき差、`lod`(level of detection)は

`1.96·sqrt(σa²/na + σb²/nb)` —— この値を超えない差は雑音と区別できない

点が足りない core は両方 `nan`。

★台帳経由(`fullseye.ledger.m3c2_distance)は宣言 out 型の distance` だけを

返す。`lod も要るときは fullseye.ledger.m3c2_distance.raw(...)`。

Raises:

ValueError: 点群 / cores が `(N,3) でない、空、normals` の数が cores と

合わない、`radius <= 0max_depth <= 0min_points < 1` のとき。

限界(honest): (1) 法線は呼び手が与える —— estimate_normals の符号は任意なので、

向きを揃えないと符号が場所ごとに反転する。(2) `lod` は雑音だけを見ており、

位置合わせの残差は含まない(Lague の原論文は登録誤差を別項として足す)。

(3) 円筒に入る点が少ない縁では `nan` になる —— 0 を返して「変化なし」に

見せない。

Reference (public): D. Lague, N. Brodu, J. Leroux, "Accurate 3D comparison of

complex topography with terrestrial laser scanner: application to the Rangitikei

canyon (N-Z)", ISPRS Journal of Photogrammetry and Remote Sensing 82 (2013) 10-26.

Hintergrundwissen (Physik und Konventionen hinter diesem Operator)

blender_interop — Blender との併用 — 形を作って fullseye で測る(軸・単位・正解データの罠)

measurement_uncertainty — 計測の不確かさと校正の知識 — 「測れている」を主張するために

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

metrics_evalpy -3.11 examples_3d/metrics_eval.py

Typkompatible Folge-Operatoren (nehmen signal als Eingabe)

fuse_to_voxel

Gleiche Kategorie (metrics)

chamfer_distance · hausdorff_distance · fscore · rmse_correspondence · normal_consistency · voxel_iou · pose_error


*Provenance: metrics3d.py — 3D Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

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