computeAdaptiveThreshold function
Computes an adaptive threshold for converting a grayscale image to black and white.
This function uses Otsu's method to select a threshold that maximizes the between-class variance of foreground and background pixels. This is more stable than a fixed offset for clean, digitally-rendered text.
Parameters:
pixels: A list of grayscale pixel values.width: The width of the image in pixels.height: The height of the image in pixels.
Returns: The computed adaptive threshold value (0..255).
Implementation
int computeAdaptiveThreshold(Uint8List pixels, int width, int height) {
final List<int> histogram = List<int>.filled(_grayscaleLevels, 0);
int total = 0;
int sumAll = 0;
for (int i = 0; i < pixels.length; i += _bytesPerPixel) {
final int gray = pixels[i];
histogram[gray] += 1;
total++;
sumAll += gray;
}
if (total == 0) {
return _grayscaleMidpoint;
}
int sumBackground = 0;
int weightBackground = 0;
double maxBetween = -1;
int bestThreshold = _grayscaleMidpoint;
for (int t = 0; t < _grayscaleLevels; t++) {
weightBackground += histogram[t];
if (weightBackground == 0) {
continue;
}
final int weightForeground = total - weightBackground;
if (weightForeground == 0) {
break;
}
sumBackground += t * histogram[t];
final int sumForeground = sumAll - sumBackground;
final double meanBackground = sumBackground / weightBackground;
final double meanForeground = sumForeground / weightForeground;
final double between =
weightBackground *
weightForeground *
(meanBackground - meanForeground) *
(meanBackground - meanForeground);
if (between > maxBetween) {
maxBetween = between;
bestThreshold = t;
}
}
return bestThreshold;
}