vol_label_shape_stats — VOLCOLOR 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)。

参考(示例数据、文献)

• 示例数据目录(下载 URL / 许可证) —— 2-D 用 skimage.data(BSD/公有领域)加合成图,3-D 给出真实数据源(Stanford/PDS 等)的下载 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)

vol_label_legend


*Provenance: volcolor.py — VOLCOLOR 算子登记表。本条目由 tools/opdocs.py md 自动生成(请勿手工编辑)。*

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