split op• Data kinds: mask → table
• Call: import fullseye as fs; fs.ledger.blob_count_interval(region: 'Any', rel_lo: 'float' = 0.05, rel_hi: 'float' = 0.15, min_prominence: 'float' = 1.0, round_tol: 'Optional[float]' = None, connectivity: 'int' = 8) -> 'dict' (implementation को सीधे call करना हो तो import blob2d; blob2d.blob_count_interval(region: 'Any', rel_lo: 'float' = 0.05, rel_hi: 'float' = 0.15, min_prominence: 'float' = 1.0, round_tol: 'Optional[float]' = None, connectivity: 'int' = 8) -> 'dict', registry से लेना हो तो opsblob.get("blob_count_interval"))
overlap हुए objects गिनता है। जब तय न हो सके, तो संख्या के बजाय interval लौटाता है (fail-closed)।
आपस में जुड़े गुच्छे के अंदर के objects, distance transform के peaks के रूप में दिखते हैं। जब दो circles overlap होते हैं तो एक neck बनती है, और neck जितनी उथली होती है (peak की prominence जितनी छोटी), उतना ही "2 हैं या 1" तय करना मुश्किल होता है। blob_seeds + blob_split एक ही h चुनकर हमेशा एक ही count लौटाते हैं —— जहाँ overlap इतना गहरा है कि तय नहीं हो सकता, वहाँ भी एक विश्वसनीय-सी संख्या निकल आती है। यह op हर peak की prominence मापता है, threshold band में आने वाले peaks को "ambiguous" मानता है, और count को lo से hi तक के interval के रूप में लौटाता है। केवल जब interval की चौड़ाई 0 हो, तभी count लौटाता है।
peak का वर्गीकरण (prominence p, height h, relative prominence p/h; h inscribed circle की radius के बराबर है):
• p >= min_prominence और p/h >= rel_hi → निश्चित peak (गिना जाता है)
• p >= min_prominence और rel_lo <= p/h < rel_hi → ambiguous (lo में नहीं गिना जाता, hi में गिना जाता है)
• बाकी → noise (grid quantisation से बने peaks; ellipses पर measurement में 0.6 px से कम)
relative prominence क्यों: जब समान radius r के दो circles overlap ratio o (centres की दूरी d = 2r(1 − o)) से overlap होते हैं, तो neck की आधी चौड़ाई w = sqrt(r² − (d/2)²) होती है, और p/h = 1 − sqrt(1 − (1 − o)²) —— radius पर निर्भर नहीं। absolute h चुनने पर, बड़े और छोटे bubbles वाली mixed image में वह सिर्फ़ एक तरफ़ ही ठीक बैठता है (poc_cell_counting ने जो कमी दर्ज की थी, उसी आकार की)। default band 0.05–0.15, overlap ratio 0.69–0.47 के बराबर है।
round_tol देने पर, वह area जिसे peaks से समझाया नहीं जा सकता, उसे भी reject किया जाता है। overlap ratio 0.7 से ऊपर जाने पर neck grid quantisation में दब जाती है और सिर्फ़ एक peak बचता है (2, 1 जैसे दिखते हैं)। इसलिए component के area की तुलना निश्चित और ambiguous peaks के inscribed circles के area के योग Σπh² से की जाती है, और अगर area > (1 + round_tol + 1/h_min) · Σπh² हो, तो upper bound खोल दी जाती है (hi = None)। 1/h_min grid quantisation का हिस्सा है (8 px या उससे बड़ी radius के discs पर ratio 1.09 या कम, 2026-10-18 का measurement)। round_tol अनुमत aspect ratio − 1 के बराबर है (aspect ratio a/b वाले ellipse का area ratio a/b होता है)। bubbles जैसे गोल objects के लिए 0.1, cells जैसे बेडौल objects के लिए लगभग 0.3। None कोई shape नहीं मानता (गहरे overlaps छूट जाते हैं)।
interval की upper bound कोई guarantee नहीं है: hi उन objects की संख्या है जो peaks के रूप में दिखे; जो objects कोई peak छोड़े बिना दब गए (जैसे किसी बड़े bubble में धँसा छोटा bubble), वे hi में भी नहीं आते। upper bound तभी खोली जाती है जब area check उन्हें पकड़ पाए। जब determined False हो, तो सिर्फ़ इतना निश्चित है कि "संख्या बताई नहीं जा सकती", और interval केवल अनुमान है (असली bubble shapes वाले semi-synthetic test में, जिस गुच्छे को अनिर्धारित बताया गया उसका true count hi से 1 ज़्यादा निकला। poc_dense_bubble_count)।
region : array_like
2-D foreground (> 0 foreground है)।
rel_lo, rel_hi : float
relative prominence का band। 0 < rel_lo <= rel_hi < 1।
min_prominence : float
prominence की absolute निचली सीमा [px]। >= 0। distance transform के quantisation से बने peaks हटाता है।
round_tol : float or None
area check की छूट (ऊपर देखें)। None पर check नहीं होता।
connectivity : {4, 8}
components और water levels के लिए connectivity।
dict
count (interval की चौड़ाई 0 हो तो int, वरना None), lo,
hi (upper bound खुली हो तो None), determined, reason,
labels (सिर्फ़ निश्चित peaks को seed बनाकर partition, int32, inscribed circles का power diagram), labels_hi
(ambiguous peaks को भी seed बनाकर partition), components (हर component का label / lo /
hi (खुली हो तो -1) / status / area / area_ratio),
peaks (हर peak का component / row / col / height /
prominence / rel_prominence / status (0 noise, 1 ambiguous, 2 निश्चित)),
params।
>>> import numpy as np
>>> yy, xx = np.mgrid[0:80, 0:120]
>>> two = ((yy - 40) ** 2 + (xx - 40) ** 2 < 400) | ((yy - 40) ** 2 + (xx - 76) ** 2 < 400)
>>> blob_count_interval(two)["count"] # overlap ratio 0.1: 2 तय होता है
2
>>> deep = ((yy - 40) ** 2 + (xx - 50) ** 2 < 400) | ((yy - 40) ** 2 + (xx - 66) ** 2 < 400)
>>> r = blob_count_interval(deep, round_tol=0.1) # overlap ratio 0.6: तय नहीं होता
>>> r["count"] is None, r["lo"]
(True, 1)
स्रोत (केवल सार्वजनिक literature): Edelsbrunner, Letscher & Zomorodian, *Discrete Comput. Geom.* 28 (2002) 511 —— persistence / Vincent & Soille, *IEEE TPAMI* 13 (1991) 583 —— watershed / Aurenhammer, *SIAM J. Comput.* 16 (1987) 78 —— power diagram (partition)।
• 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_dense_bubble_count — py -3.11 examples/poc_dense_bubble_count.py
table को input के रूप में लेते हैं)—
split)blob_distance · blob_seeds · blob_split
*Provenance: blob2d.py — BLOB operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.