detectLighting static method

LightingDetectionResult detectLighting(
  1. CameraImage cameraImage,
  2. Face face
)

Detects lighting quality in camera images.

Analyzes the cameraImage focusing on the detected face region. Returns a LightingDetectionResult with lighting metrics and issues.

The detection analyzes:

  • Average brightness
  • Contrast levels
  • Overexposure and underexposure ratios
  • Specific lighting issues (too bright, too dark, etc.)

Implementation

static LightingDetectionResult detectLighting(
  CameraImage cameraImage,
  Face face,
) {
  try {
    final faceRect = face.boundingBox;

    // Extract face region from camera image
    final facePixels = _extractFacePixels(cameraImage, faceRect);
    if (facePixels.isEmpty) {
      return LightingDetectionResult(
        isGoodLighting: true, // Default to good lighting if can't analyze
        avgBrightness: 128, // Neutral value
        contrast: 30,
        overexposureRatio: 0.0,
        underexposureRatio: 0.0,
        issue: null, // No issue if can't analyze
      );
    }

    // Calculate lighting metrics
    final avgBrightness = _calculateAverageBrightness(facePixels);
    final contrast = _calculateContrast(facePixels);
    final overexposureRatio = _calculateOverexposureRatio(facePixels);
    final underexposureRatio = _calculateUnderexposureRatio(facePixels);

    // Much more lenient lighting requirements
    LightingIssue? issue;
    bool isGoodLighting = true;
    // Only fail lighting if it's REALLY bad
    if (avgBrightness < _minBrightness && contrast < 5) {
      issue = LightingIssue.tooWarm;
      isGoodLighting = false;
    } else if (avgBrightness > _maxBrightness && overexposureRatio > 0.6) {
      issue = LightingIssue.tooBright;
      isGoodLighting = false;
    } else if (contrast < 5 && avgBrightness < 40) {
      // Much stricter
      issue = LightingIssue.lowContrast;
      isGoodLighting = false;
    } else if (overexposureRatio > _maxOverexposureRatio &&
        avgBrightness > 200) {
      issue = LightingIssue.overexposed;
      isGoodLighting = false;
    } else if (underexposureRatio > _maxUnderexposureRatio &&
        avgBrightness < 30) {
      issue = LightingIssue.underexposed;
      isGoodLighting = false;
    }

    return LightingDetectionResult(
      isGoodLighting: isGoodLighting,
      avgBrightness: avgBrightness,
      contrast: contrast,
      overexposureRatio: overexposureRatio,
      underexposureRatio: underexposureRatio,
      issue: issue,
    );
  } catch (e) {
    debugPrint('Error in lighting detection: $e');
    return LightingDetectionResult(
      isGoodLighting: true, // Default to good lighting on error
      avgBrightness: 128,
      contrast: 30,
      overexposureRatio: 0.0,
      underexposureRatio: 0.0,
      issue: null,
    );
  }
}