fingerprint/lib/core/services/quality_checker.dart
Aastha Shrivastava 3132b7e8cd first commit
2026-01-17 12:54:01 +05:30

81 lines
2.3 KiB
Dart

import 'package:opencv_dart/opencv_dart.dart' as cv;
import '../../domain/entities/quality_result.dart';
class QualityChecker {
static double getBlurScore(cv.Mat mat) {
final laplacian = cv.laplacian(mat, cv.MatType.CV_64F);
final (_, stddev) = cv.meanStdDev(laplacian);
laplacian.dispose();
return stddev.val1 * stddev.val1;
}
static double checkIllumination(cv.Mat mat) {
final meanScalar = cv.mean(mat);
return meanScalar.val1;
}
static bool checkPosition(cv.Mat mat) {
final (_, threshMat) = cv.threshold(mat, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU);
final (contours, hierarchy) = cv.findContours(threshMat, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);
threshMat.dispose();
hierarchy.dispose();
if (contours.isEmpty) return false;
double maxArea = 0;
cv.Rect? maxRect;
for (int i = 0; i < contours.length; i++) {
final contour = contours[i];
final area = cv.contourArea(contour);
if (area > maxArea) {
maxArea = area;
maxRect = cv.boundingRect(contour);
}
}
if (maxRect == null) return false;
final imgW = mat.cols;
final imgH = mat.rows;
final guideX = imgW ~/ 4;
final guideY = imgH ~/ 4;
final guideW = imgW ~/ 2;
final guideH = imgH ~/ 2;
final objCx = maxRect.x + maxRect.width / 2;
final objCy = maxRect.y + maxRect.height / 2;
final bool isCentered = objCx >= guideX && objCx <= (guideX + guideW) &&
objCy >= guideY && objCy <= (guideY + guideH);
final bool isBigEnough = maxArea > (imgW * imgH * 0.25);
return isCentered && isBigEnough;
}
static QualityResult analyze(cv.Mat mat) {
final blur = getBlurScore(mat);
final brightness = checkIllumination(mat);
final positionValid = checkPosition(mat);
final bool isSharp = blur > 100.0;
final bool isLit = brightness > 40.0 && brightness < 220.0;
final normBlur = (blur / 500.0).clamp(0.0, 1.0);
final normBright = 1.0 - ((brightness - 128).abs() / 128.0).clamp(0.0, 1.0);
final score = (normBlur * 0.6) + (normBright * 0.4);
return QualityResult(
passed: isSharp && isLit && positionValid,
score: score,
blurScore: blur,
brightness: brightness,
isPositionValid: positionValid,
);
}
}