shape_index — 3D curvature op

• 데이터 종류: points → descriptor

• 호출: import fullseye as fs; fs.ledger.shape_index(points, k=25, normals=None)(구현을 직접 호출하려면 import curvature3d; curvature3d.shape_index(points, k=25, normals=None), 원장에서 가져오려면 ops3d.get("shape_index"))

사용법

Koenderink 의 shape index s∈-1,1. → (N,).

배꼽점/평면 판정은 곡률 스케일 상대(절대 임계값 없음). 완만한 볼록/오목(곡률이 미소해도)은부호=오목·볼록을 유지하고, 평면은 데이터 전체의 곡률 스케일에 대해 상대적으로 0 인 점만 s=0 으로 한다.

normals(방향이 정해진 참조 법선, (N,3))를 지정하지 않으면 열린 면의 오목/볼록 부호는 부정(볼록 크기로 보고). 방향이 정해진 법선을 넘기면 대역 방향에 맞추어 올바른 부호(오목 구=cup → -1)를 낸다.

계산(각 점, principal_curvatures 와 같은 피팅):

• 평면 판정: curvedness sqrt((k1² + k2²) / 2) 가 전체 점의 curvedness 중앙값 × 1e-3 미만이면 s = 0. 중앙값이 0(곡률 신호 없음)이면 전체 점이 0.

• 배꼽점 판정: |k1 - k2| < 1e-2 × (|k1| + |k2|) 이면 s = sign(k1 + k2)(엄밀히 ±1).

• 그 밖: s = (2/π) · arctan((k1 + k2) / (k1 - k2)).

• 임계값은 절댓값이 아니라 데이터 전체의 곡률 스케일 상대 이므로, 같은 형태라도 다른 점과의 혼재 정도에 따라 평면으로 취급되는 점이 바뀐다. 단일 점군을 분류하는 전제로 쓴다.

• 근방이 5 점 미만인 점은 k1 = k2 = 0 → 평면(0). k 는 N-1 로 잘린다.

• normals 는 (N,3) 이고 유한하며 0 이 아닌 행(ValueError). 지정하지 않으면 열린 면의 부호는 부정(볼록 쪽).

• 굽은 정도의 강도는 포함하지 않는다. 강도도 필요하면 principal_curvatures 의 2 개 값을 (N,2) 로 나란히 놓아 curvature_to_shape_index 에 통과시킨다.

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

• blas_threads_and_memory — 행렬 분해가 느린 이유 — BLAS 스레드·캐시·메모리 배치

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

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

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

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

• curvature_grasp — py -3.11 examples_3d/curvature_grasp.py

• itokawa_curvature — py -3.11 examples_3d/itokawa_curvature.py

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

fuse_to_voxel · shape_distance

같은 카테고리(curvature)

principal_curvatures · mean_curvature · gaussian_curvature · estimate_normals


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

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