histogramAutoLevels static method

Uint8List histogramAutoLevels(
  1. Uint8List gray,
  2. int width,
  3. int height, {
  4. double lowPercentile = 0.01,
  5. double highPercentile = 0.99,
})

Applies histogram auto-levels using percentile-based stretching.

Maps the lowPercentilehighPercentile intensity range to 0–255, clipping outliers. More robust than simple min-max contrast stretch.

Inspired by Scanbot SDK's auto-enhancement algorithm.

Implementation

static Uint8List histogramAutoLevels(
  Uint8List gray,
  int width,
  int height, {
  double lowPercentile = 0.01,
  double highPercentile = 0.99,
}) {
  if (gray.isEmpty) return gray;

  // Build histogram
  final histogram = Int32List(256);
  for (int i = 0; i < gray.length; i++) {
    histogram[gray[i]]++;
  }

  // Find percentile bounds
  final total = gray.length;
  final lowCount = (total * lowPercentile).round();
  final highCount = (total * highPercentile).round();

  int low = 0, high = 255;
  int cumulative = 0;
  for (int i = 0; i < 256; i++) {
    cumulative += histogram[i];
    if (cumulative >= lowCount && low == 0) low = i;
    if (cumulative >= highCount) {
      high = i;
      break;
    }
  }

  if (high <= low) return gray;

  // Apply linear stretch
  final result = Uint8List(gray.length);
  final scale = 255.0 / (high - low);
  for (int i = 0; i < gray.length; i++) {
    result[i] = ((gray[i] - low) * scale).clamp(0, 255).toInt();
  }

  return result;
}