measure op• 데이터 종류: labels → table
• 호출: import fullseye as fs; fs.ledger.vol_label_shape_stats(labels, spacing=None, shape: 'bool' = True)(구현을 직접 호출하려면 import volcolor; volcolor.vol_label_shape_stats(labels, spacing=None, shape: 'bool' = True), 원장에서 가져오려면 opsvolcolor.get("vol_label_shape_stats"))
성분별로 선형 시간에 낼 수 있는 정량값(부피·무게중심·박스·주성분 형상 지표).
volops.vol_region_props 의 자매이지만, 목적이 다르다:
• 저쪽은 surface_area 와 Wadell sphericity 를 낸다. 그 때문에성분마다 marching cubes 를 돌리므로, 성분 수에 비례해 Python 루프가돈다(1 복셀 1 라벨의 병적 입력에서 급속히 무거워진다).
• 이쪽은 np.bincount 의 가중 총합만으로 끝나는 양으로 한정한다. 라벨 배열 1 개당 9 회의 bincount = O(N + n). 실측(connectivity=26, 1 복셀 1 라벨의 체커보드 = 병적 입력):
16 ** 3 = 4096 복셀 / 512 성분 = 0.0037 s, 32 ** 3 = 32768 / 4096 =
0.0350 s, 64 ** 3 = 262144 / 32768 = 0.2556 s, 128 ** 3 = 2097152 / 262144 =
2.3122 s. 복셀 8 배마다 9.5 / 7.3 / 9.0 배(이차라면 64 배)이며,
전 구간에서 약 1.1 마이크로초/복셀. 같은 128 ** 3 의 색칠은 0.0357 s.
(참고: volops.vol_region_props(surface="faces") 는 같은 16 ** 3 에서
0.0121 s ―― 성분마다의 Python 루프가 있는 만큼 3.5 배. marching cubes 를
쓰는 기본값 surface="auto" 는 더 무겁다.)
label voxel_count volume centroid bbox 의 5 가지는 volops.vol_region_props 와 동일한 정의 · 동일한 값이다(tests/test_volcolor.py::test_stats_agree_with_vol_region_props_exactly 가엄밀 일치로 고정). bbox 는 (z0, z1, y0, y1, x0, x1) 이며 상한은 배타적.
추가로 반환하는 것:
centroid_mm (z, y, x) 물리 좌표(spacing 이 없으면 voxel 과 같은 값)·
extent bbox 의 물리 치수 (dz, dy, dx) · equivalent_diameter
(6V/pi)**(1/3) · touches_border bbox 가 볼륨 끝에 닿는지 ·
principal_extent 공분산 고윳값의 제곱근 (s1 >= s2 >= s3)(물리 단위) ·
linearity (l1-l2)/l1 · planarity (l2-l3)/l1 · isotropy
l3/l1 · elongation sqrt(l1/l2).
elongation 은 무한이 될 수 있다(계약): l1 > 0 이고 l2 == 0, 즉 두께 1 복셀의 완전한 직선 성분에서는 inf 를 반환한다. 0 으로 나눈 사고가아니라 "제 2 축 방향으로 퍼짐이 없다"는 사실이며, 반올림하면 가늘고 긴 정도의 순위가조용히 뒤바뀐다. 단일 복셀(l1 == 0)은 등방적인 점이므로 1.0.
spacing 을 넘기는 것을 잊으면 숫자도 결론도 바뀐다. 실측 ―― 반지름 6 mm 의 구를 spacing = (3.0, 1.0, 1.0) mm 의 이방 격자(z 만 3 배 성김)로 샘플링하면 293 복셀이 된다. 닫힌 식의 참값은 4/3 pi 6**3 = 904.78 mm**3:
• spacing 있음 = 879.0 mm ** 3(오차 -2.85 %), isotropy = 0.7349(거의 등방 = 올바름).
• spacing 없음 = 293.0(voxel 단위. mm ** 3 으로 읽으면 오차 -67.62 %), isotropy = 0.0817 ―― 구가 "판"으로 보인다. 이방성을 무시하면형상 지표는 파탄 나고, 게다가 유한하고 타당해 보이는 값으로 반환된다.
• 등가 직경도 11.8849 mm 대 8.2406 으로 1.44 배 어긋난다.
수치상의 주의: 2 차 모멘트는 E[x**2] - E[x]**2 로 구하므로, 좌표가크고 퍼짐이 작은 성분에서는 자릿수 손실이 일어날 수 있다. 상한 MAX_COLOR_VOXELS (1 변 ~2000 까지)에서는 E[x**2] ~ 4e6 에 대해 float64 의 상대 정밀도 1e-16 = 절대 1e-10 으로, 복셀 단위의 분산에 대해 10 자리의 여유가 있다. 그보다 큰볼륨은 ROI 를 잘라낸 다음 넘길 것(상한이 있는 것은 이 때문이기도 하다).
*shape* 를 False 로 하면 공분산(9 개 중 6 개의 bincount)을 생략하고, principal_extent 이하의 5 항목을 반환하지 않는다 ―― 부피 필터만 필요할때 O(N) 의 임시 배열을 1 개로 줄일 수 있다.
라벨 오름차순으로 list[dict] 를 반환한다(실재하는 라벨만 ―― 번호에 결번이 있어도 labels.max() 만큼의 빈 dict 는 반환하지 않는다).
• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.
• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.
• 알고리즘의 정전(저자·연도)과 용도는 위의 패밀리 사용 가이드에 적혀 있습니다.
• poc_cold_chain_excursion — py -3.11 examples/poc_cold_chain_excursion.py
• voxel_labels_color — py -3.11 examples/voxel_labels_color.py
table 를 입력으로 받는 것)—
measure)*Provenance: volcolor.py — VOLCOLOR 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.