measure op• Data kinds: labels → table
• Call: import fullseye as fs; fs.ledger.vol_label_shape_stats(labels, spacing=None, shape: 'bool' = True) (implementation को सीधे call करना हो तो import volcolor; volcolor.vol_label_shape_stats(labels, spacing=None, shape: 'bool' = True), registry से लेना हो तो opsvolcolor.get("vol_label_shape_stats"))
हर component की वे मात्राएँ जो linear time में निकाली जा सकती हैं (volume, centroid, box, principal component shape index)।
volops.vol_region_props का sibling है, पर उद्देश्य अलग है:
• वह surface_area और Wadell sphericity देता है। इसके लिए वह हर component पर marching cubes चलाता है, इसलिए component की संख्या के अनुपात में Python loop चलता है (1 voxel पर 1 label वाले pathological input में तेज़ी से भारी हो जाता है)।
• यह केवल उन मात्राओं तक सीमित है जो np.bincount के weighted sum से ही मिल जाती हैं। हर 1 label array पर 9 बार bincount = O(N + n)। measured (connectivity=26, 1 voxel पर 1 label वाला checkerboard = pathological input):
16 ** 3 = 4096 voxel / 512 component = 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 गुना voxel पर 9.5 / 7.3 / 9.0 गुना (quadratic होता तो 64 गुना),
पूरे दायरे में लगभग 1.1 microsecond/voxel। उसी 128 ** 3 को रंगने में 0.0357 s।
(संदर्भ: volops.vol_region_props(surface="faces") उसी 16 ** 3 पर
0.0121 s लेता है -- हर component के Python loop के कारण 3.5 गुना। marching cubes
इस्तेमाल करने वाला default 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) है और ऊपरी सीमा exclusive है।
इसके अलावा लौटाया जाता है:
centroid_mm (z, y, x) physical coordinate (spacing न हो तो voxel के बराबर) ·
extent bbox का physical आकार (dz, dy, dx) · equivalent_diameter
(6V/pi)**(1/3) · touches_border क्या bbox volume के किनारे को छूता है ·
principal_extent covariance eigenvalue का square root (s1 >= s2 >= s3) (physical unit) ·
linearity (l1-l2)/l1 · planarity (l2-l3)/l1 · isotropy
l3/l1 · elongation sqrt(l1/l2)।
elongation अनंत हो सकता है (contract): l1 > 0 और l2 == 0, यानी 1 voxel मोटी बिल्कुल सीधी रेखा वाले component में inf लौटता है। यह 0 से भाग देने की दुर्घटना नहीं, बल्कि "2nd axis की दिशा में कोई फैलाव नहीं" का तथ्य है; round करने पर पतलेपन का क्रम चुपचाप बदल जाता है। अकेला voxel (l1 == 0) isotropic point है, इसलिए 1.0।
spacing देना भूलने पर अंक और निष्कर्ष दोनों बदल जाते हैं। measured -- 6 mm radius वाले sphere को spacing = (3.0, 1.0, 1.0) mm के anisotropic grid (केवल z 3 गुना मोटा) पर sample करने पर 293 voxel बनते हैं। closed form का ground truth 4/3 pi 6**3 = 904.78 mm**3 है:
• spacing के साथ = 879.0 mm ** 3 (error -2.85 %), isotropy = 0.7349 (लगभग isotropic = सही)।
• spacing के बिना = 293.0 (voxel unit; mm ** 3 पढ़ने पर error -67.62 %), isotropy = 0.0817 -- sphere "प्लेट" जैसा दिखता है। anisotropy को नज़रअंदाज़ करने पर shape index टूट जाते हैं, और ऊपर से finite और उचित दिखने वाले मान के रूप में लौटते हैं।
• equivalent diameter भी 11.8849 mm बनाम 8.2406, यानी 1.44 गुना खिसकता है।
numerical सावधानी: 2nd moment E[x**2] - E[x]**2 से निकाला जाता है, इसलिए coordinate बड़े और फैलाव छोटा हो तो significant digits का loss हो सकता है। सीमा MAX_COLOR_VOXELS (1 side ~2000 तक) पर E[x**2] ~ 4e6 के मुक़ाबले float64 की relative precision 1e-16 = absolute 1e-10 है, यानी voxel unit के variance की तुलना में 10 अंकों की गुंजाइश। इससे बड़े volume को पहले ROI काटकर दें (सीमा होने का एक कारण यह भी है)।
*shape* को False करने पर covariance (9 में से 6 bincount) छोड़ दिया जाता है, और principal_extent से आगे के 5 item नहीं लौटते -- जब केवल volume filter चाहिए तब O(N) के temporary array 1 तक घट जाते हैं।
label के बढ़ते क्रम में list[dict] लौटाता है (केवल मौजूद label -- numbering में ख़ाली नंबर हों तब भी labels.max() जितने ख़ाली dict नहीं लौटते)।
• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।
• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।
• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।
• 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 को input के रूप में लेते हैं)—
measure)*Provenance: volcolor.py — VOLCOLOR operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.