Balanced histogram thresholding: Difference between revisions

Content deleted Content added
No edit summary
Fix issue with python code
 
(7 intermediate revisions by 6 users not shown)
Line 1:
{{short description|Type of image thresholding}}
In [[image processing]], the '''balanced histogram thresholding method''' (BHT),<ref>A. Anjos and H. Shahbazkia. Bi-Level Image Thresholding - A Fast Method. BIOSIGNALS 2008. Vol:2. P:70-76.</ref> is a very simple method used for automatic image [[Thresholding (image processing)|thresholding]]. Like [[Otsu's Method]]<ref>Nobuyuki Otsu (1979). "A threshold selection method from gray-level histograms". IEEE Trans. Sys., Man., Cyber. 9: 62–66.</ref> and the '''Iterative Selection Thresholding Method''',<ref>Ridler TW, Calvard S. (1978) Picture thresholding using an iterative selection method, IEEE Trans. System, Man and Cybernetics, SMC-8: 630-632.</ref> this is a [[histogram]] based thresholding method. This approach assumes that the image is divided in two main classes: The '''background''' and the '''foreground'''. The '''BHT''' method tries to find the optimum threshold level that divides the histogram in two classes.
[[File:Lovely spider.jpeg|thumb | 200px | right | Original image.]]
Line 33 ⟶ 34:
}
</syntaxhighlight>
 
 
 
The following, is a possible implementation in the [[Python (programming language)|Python]] language:
<syntaxhighlight lang="python">
def balanced_histogram_thresholding(histogram, minimum_bin_count: int = 5, jump: int = 1) -> int:
def bht(hist, min_count=5):
"""
n_bins = len(hist) # assumes 1D histogram
Determines an optimal threshold by balancing the histogram of an image,
h_s = 0
focusing on significant histogram bins to segment the image into two parts.
while hist[h_s] < min_count: h_s += 1 # ignore small counts at start
 
h_e = n_bins - 1
Args:
while hist[h_e] < min_count: h_e -=1 # ignore small counts at end
# use mean intensity ofhistogram (list): The histogram of the image as center;a alternatively:list of integers, (h_s+h_e)/2)
where each element represents the count of pixels
h_c = int(round(np.average(np.linspace(0, 2**8-1, n_bins), weights=hist)))
at a specific intensity level.
w_l = np.sum(hist[h_s:h_c]) # weight in the left part
minimum_bin_count (int): Minimum count for a bin to be considered in the
w_r = np.sum(hist[h_c:h_e+1]) # weight in the right part
thresholding process. Bins with counts below this
value are ignored, reducing the effect of noise.
jump (int): Step size for adjusting the threshold during iteration. Larger values
speed up convergence but may skip the optimal threshold.
 
Returns:
int: The calculated threshold value. This value represents the intensity level
(i.e. the index of the input histogram) that best separates the significant
parts of the histogram into two groups, which can be interpreted as foreground
h_s +=and background. 1
If the function returns -1, it indicates that the algorithm was unable to find
a suitable threshold within the constraints (e.g., all bins are below the
minimum_bin_count).
"""
# Find the start and end indices where the histogram bins are significant
h_sstart_index = 0
while start_index < len(histogram) and histogram[start_index] < minimum_bin_count:
start_index += 1
end_index = len(histogram) - 1
while h_s < h_e:
while end_index >= 0 and histogram[end_index] < minimum_bin_count:
if w_l > w_r: # left part became heavier
w_lend_index -= hist[h_s]1
 
h_s += 1
# Check if no valid bins are found
else: # right part became heavier
if start_index >= end_index:
w_r -= hist[h_e]
return -1 # h_eIndicates -=an 1error or non-applicability
 
new_c = int(round((h_e + h_s)/2)) # re-center the weighing scale
# Initialize threshold
threshold = (start_index + end_index) // 2
 
# Iteratively adjust the threshold
while start_index <= end_index:
# Calculate weights on both sides of the threshold
weight_left = sum(histogram[start_index:threshold])
weight_right = sum(histogram[threshold:end_index + 1])
 
# Adjust the threshold based on the weights
if weight_left > weight_right:
w_rstart_index += hist[h_c]jump
elif weight_left < weight_right:
w_rend_index -= hist[h_e]jump
else: # Equal weights; move both indices
w_lstart_index += hist[h_c]jump
w_rend_index -= hist[h_c]jump
 
if new_c < h_c: # move bin toCalculate the othernew sidethreshold
threshold = (start_index + w_lend_index) -=// hist[h_c]2
w_r += hist[h_c]
elif new_c > h_c:
w_l += hist[h_c]
w_r -= hist[h_c]
h_c = new_c
 
return h_cthreshold
</syntaxhighlight>
 
Line 74 ⟶ 102:
 
==External links==
* [http://w3.ualg.pt/~aanjos/prototype/BHThresholding_.jar ImageJ Plugin] {{Webarchive|url=https://web.archive.org/web/20131017205614/http://w3.ualg.pt/~aanjos/prototype/BHThresholding_.jar |date=2013-10-17 }}
* [https://www.youtube.com/watch?v=rKWK4O4dZQ8 Otsu ''vs''. BHT]
 
{{DEFAULTSORT:Balanced Histogram Thresholding}}
[[Category:Image segmentation]]
[[Category:Articles with example Python (programming language) code]]