histogramAutoLevels static method
Applies histogram auto-levels using percentile-based stretching.
Maps the lowPercentile–highPercentile 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;
}