computeAdaptiveThreshold function

int computeAdaptiveThreshold(
  1. Uint8List pixels,
  2. int width,
  3. int height
)

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;
}