detectBlur static method

BlurDetectionResult detectBlur(
  1. CameraImage cameraImage,
  2. Face face, {
  3. 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,
      ),
    );
  }
}