m3c2_distance — 3D metrics op

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

• 호출: import fullseye as fs; fs.ledger.m3c2_distance(a, b, cores, normals, radius, max_depth=None, min_points=4)(구현을 직접 호출하려면 import metrics3d; metrics3d.m3c2_distance(a, b, cores, normals, radius, max_depth=None, min_points=4), 원장에서 가져오려면 ops3d.get("m3c2_distance"))

• 원장 경유의 반환값: fullseye.ledger.m3c2_distance(...) 는 선언된 out 형 signal 의 값만 반환합니다(실제 함수는 보조 정보도 반환). 버려진 쪽이 필요하면 fullseye.ledger.m3c2_distance.raw(...) 를 쓰거나 metrics3d.m3c2_distance 를 직접 호출하세요.

사용법

2개 시점의 점군 차이를 법선 방향으로 측정한다(M3C2). → (distance, lod)의 2개.

최근접 거리(chamfer / C2C)는 "가장 가까운 점까지의 거리"이므로, 기울어진 면에서는면을 따른 어긋남까지 거리로 세어 버린다. 지형·구조물의 변화 검출에서는 그것이 "다시 쟀을 뿐인데 검출되는 가짜 변화"의 주원인이 된다(poc_structure_4d_deterioration 의 실측: 열화 0으로 다시 쟀을 뿐인데 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 <= 0, max_depth <= 0, min_points < 1일 때.

한계(honest): (1) 법선은 호출자가 준다 —— estimate_point_normals의 기본 부호는무게중심 기준이므로, viewpoint 나 orient_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.

배경 지식 가이드(이 연산자 앞에 있는 물리·규약)

• blender_interop — Blender와 함께 쓰기 — 형상을 만들고 fullseye로 측정(축·단위·정답 데이터의 함정)

• measurement_uncertainty — 측정 불확도와 교정 지식 — ‘측정되고 있다’고 주장하려면

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

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

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

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

• metrics_eval — py -3.11 examples_3d/metrics_eval.py

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

fuse_to_voxel

같은 카테고리(metrics)

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


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

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