detectBlur static method
BlurDetectionResult
detectBlur(
- CameraImage cameraImage,
- Face face, {
- double threshold = _blurThreshold,
Detects blur in camera images using multiple quality metrics.
Analyzes the cameraImage focusing on the detected face region.
Returns a BlurDetectionResult with detailed quality information.
The detection uses:
- Face size analysis
- Landmark stability check
- Laplacian variance calculation (optional based on image format)
Implementation
static BlurDetectionResult detectBlur(
CameraImage cameraImage,
Face face, {
double threshold = _blurThreshold,
}) {
try {
// Method 1: Face size check (more lenient)
final faceArea = face.boundingBox.width * face.boundingBox.height;
final isSmallFace = faceArea < _minFaceSize;
// Method 2: Face landmark stability (more lenient)
final landmarkStability = _checkLandmarkStability(face);
// Method 3: Laplacian variance (skip if causing issues)
double laplacianVariance = 0.0;
bool skipLaplacianCheck = false; // Add option to skip this check
if (!skipLaplacianCheck &&
(cameraImage.format.group == ImageFormatGroup.yuv420 ||
cameraImage.format.group == ImageFormatGroup.nv21)) {
laplacianVariance = _calculateLaplacianVariance(
cameraImage,
face.boundingBox,
);
}
// NEW: Much more forgiving combination logic
// Only mark as blurry if MULTIPLE conditions are bad, not just one
int badConditions = 0;
if (isSmallFace) badConditions++;
if (!landmarkStability) badConditions++;
if (!skipLaplacianCheck &&
laplacianVariance > 0 &&
laplacianVariance < threshold) {
badConditions++;
}
// Only consider blurry if at least 2 conditions are bad AND face is very small
final isBlurry = badConditions >= 2 && isSmallFace;
return BlurDetectionResult(
isBlurry: isBlurry,
faceArea: faceArea,
laplacianVariance: laplacianVariance,
landmarkStability: landmarkStability,
confidence: _calculateBlurConfidence(
faceArea,
laplacianVariance,
landmarkStability,
),
debugInfo: BlurDebugInfo(
isSmallFace: isSmallFace,
badConditions: badConditions,
skipLaplacianCheck: skipLaplacianCheck,
),
);
} catch (e) {
debugPrint('Error in blur detection: $e');
return BlurDetectionResult(
isBlurry: false, // Default to NOT blurry on error
faceArea: 0,
laplacianVariance: 0,
landmarkStability: false,
confidence: 0.0,
debugInfo: BlurDebugInfo(
isSmallFace: true,
badConditions: 0,
skipLaplacianCheck: true,
),
);
}
}