Thresholding with Otsu's method
Thresholding turns a grayscale image into a binary one: pixels above a threshold become foreground (1) and the rest become background (0). It is a basic step in document scanning, microscopy, and many segmentation pipelines. The difficulty is choosing the threshold, since a fixed value fails when lighting changes.
Python
def otsu(pixels):
histogram = [0] * 256
for pixel in pixels:
histogram[pixel] += 1
total = len(pixels)
total_sum = sum(level * count for level, count in enumerate(histogram))
best_variance, best_threshold = -1.0, 0
weight_dark = sum_dark = 0
for t in range(256):
weight_dark += histogram[t]
if weight_dark == 0:
continue
weight_bright = total - weight_dark
if weight_bright == 0:
break
sum_dark += t * histogram[t]
mean_dark = sum_dark / weight_dark
mean_bright = (total_sum - sum_dark) / weight_bright
between = weight_dark * weight_bright * (mean_dark - mean_bright) ** 2
if between > best_variance:
best_variance, best_threshold = between, t
return best_threshold
pixels = [28, 30, 35, 40, 33, 31, 38, 29, 205, 210, 215, 200, 220, 208, 212, 218]
threshold = otsu(pixels)
print(threshold)
print([1 if pixel > threshold else 0 for pixel in pixels])