analyzeBlur static method
Analyzes blur level using discrete Laplacian operator.
Implementation
static BlurAnalysis analyzeBlur(
Uint8List imageBytes, {
required int width,
required int height,
}) {
if (imageBytes.isEmpty || width <= 2 || height <= 2) {
return const BlurAnalysis(
severity: BlurSeverity.heavy,
score: 1.0,
laplacianVariance: 0.0,
);
}
// Compute discrete Laplacian variance as blur metric
double sum = 0;
double sumSquared = 0;
int count = 0;
for (int y = 1; y < height - 1 && y * width < imageBytes.length; y++) {
for (int x = 1; x < width - 1; x++) {
final idx = y * width + x;
if (idx + width < imageBytes.length && idx - width >= 0) {
// Laplacian kernel: [0,-1,0; -1,4,-1; 0,-1,0]
final laplacian = 4 * imageBytes[idx] -
imageBytes[idx - 1] -
imageBytes[idx + 1] -
imageBytes[idx - width] -
imageBytes[idx + width];
sum += laplacian;
sumSquared += laplacian * laplacian;
count++;
}
}
}
if (count == 0) {
return const BlurAnalysis(
severity: BlurSeverity.heavy,
score: 1.0,
laplacianVariance: 0.0,
);
}
final mean = sum / count;
final variance = (sumSquared / count) - (mean * mean);
final normalizedVariance = variance.abs();
// Map variance to blur severity
final BlurSeverity severity;
final double blurScore;
if (normalizedVariance > 500) {
severity = BlurSeverity.sharp;
blurScore = 0.0;
} else if (normalizedVariance > 200) {
severity = BlurSeverity.mild;
blurScore = 0.25;
} else if (normalizedVariance > 50) {
severity = BlurSeverity.moderate;
blurScore = 0.6;
} else {
severity = BlurSeverity.heavy;
blurScore = 0.9;
}
return BlurAnalysis(
severity: severity,
score: blurScore,
laplacianVariance: normalizedVariance,
);
}