Parcourir la source

Use full file on face detection

laurenspriem il y a 1 an
Parent
commit
74d1cbb01f

+ 1 - 2
mobile/lib/face/db.dart

@@ -1,6 +1,5 @@
 import 'dart:async';
 import "dart:math";
-import "dart:typed_data";
 
 import "package:collection/collection.dart";
 import "package:flutter/foundation.dart";
@@ -335,7 +334,7 @@ class FaceMLDataDB {
   ///
   /// Only selects faces with score greater than [minScore] and blur score greater than [minClarity]
   Future<Map<String, (int?, Uint8List)>> getFaceEmbeddingMap({
-    double minScore = 0.8,
+    double minScore = 0.78,
     int minClarity = kLaplacianThreshold,
     int maxRows = 20000,
   }) async {

+ 5 - 1
mobile/lib/services/face_ml/face_detection/yolov5face/onnx_face_detection.dart

@@ -34,7 +34,7 @@ class YoloOnnxFaceDetection {
   static const kInputWidth = 640;
   static const kInputHeight = 640;
   static const kIouThreshold = 0.4;
-  static const kMinScoreSigmoidThreshold = 0.8;
+  static const kMinScoreSigmoidThreshold = 0.7;
 
   bool isInitialized = false;
 
@@ -373,6 +373,10 @@ class YoloOnnxFaceDetection {
 
     final relativeDetections = _yoloPostProcessOutputs(outputs, newSize);
 
+    dev.log(
+      '${relativeDetections.length} faces detected, with scores ${relativeDetections.map((e) => e.score).toList()}',
+    );
+
     stopwatch.stop();
     _logger.info(
       'predict() face detection executed in ${stopwatch.elapsedMilliseconds}ms',

+ 14 - 0
mobile/lib/services/face_ml/face_detection/yolov5face/yolo_filter_extract_detections.dart

@@ -1,3 +1,5 @@
+import 'dart:developer' as dev show log;
+
 import "package:photos/services/face_ml/face_detection/detection.dart";
 
 List<FaceDetectionRelative> yoloOnnxFilterExtractDetections(
@@ -23,6 +25,18 @@ List<FaceDetectionRelative> yoloOnnxFilterExtractDetections(
     output.add(rawDetection);
   }
 
+  if (output.isEmpty) {
+    double maxScore = 0;
+    for (final result in results) {
+      if (result[4] > maxScore) {
+        maxScore = result[4];
+      }
+    }
+    dev.log(
+      'No face detections found above the minScoreSigmoidThreshold of $minScoreSigmoidThreshold. The max score was $maxScore.',
+    );
+  }
+
   for (final List<double> rawDetection in output) {
     // Get absolute bounding box coordinates in format [xMin, yMin, xMax, yMax] https://github.com/deepcam-cn/yolov5-face/blob/eb23d18defe4a76cc06449a61cd51004c59d2697/utils/general.py#L216
     final xMinAbs = rawDetection[0] - rawDetection[2] / 2;

+ 9 - 16
mobile/lib/services/face_ml/face_ml_service.dart

@@ -195,8 +195,7 @@ class FaceMlService {
         switch (function) {
           case FaceMlOperation.analyzeImage:
             final int enteFileID = args["enteFileID"] as int;
-            final String smallDataPath = args["smallDataPath"] as String;
-            final String largeDataPath = args["largeDataPath"] as String;
+            final String imagePath = args["filePath"] as String;
             final int faceDetectionAddress =
                 args["faceDetectionAddress"] as int;
             final int faceEmbeddingAddress =
@@ -214,13 +213,13 @@ class FaceMlService {
             // Get the faces
             final List<FaceDetectionRelative> faceDetectionResult =
                 await FaceMlService.detectFacesSync(
-              smallDataPath,
+              imagePath,
               faceDetectionAddress,
               resultBuilder: resultBuilder,
             );
 
             dev.log(
-                "${faceDetectionResult.length} faces detected: completed `detectFaces` function, in "
+                "${faceDetectionResult.length} faces detected: completed `detectFacesSync` function, in "
                 "${stopwatch.elapsedMilliseconds} ms");
 
             // If no faces were detected, return a result with no faces. Otherwise, continue.
@@ -236,7 +235,7 @@ class FaceMlService {
             // Align the faces
             final Float32List faceAlignmentResult =
                 await FaceMlService.alignFacesSync(
-              largeDataPath,
+              imagePath,
               faceDetectionResult,
               resultBuilder: resultBuilder,
             );
@@ -478,7 +477,9 @@ class FaceMlService {
       }
       final List<Face> faces = [];
       if (!result.hasFaces) {
-        debugPrint('No faces detected for file with name:${enteFile.displayName}');
+        debugPrint(
+          'No faces detected for file with name:${enteFile.displayName}',
+        );
         faces.add(
           Face(
             '${result.fileId}-0',
@@ -721,23 +722,16 @@ class FaceMlService {
     _checkEnteFileForID(enteFile);
     await ensureInitialized();
 
-    final String? thumbnailPath = await _getImagePathForML(
-      enteFile,
-      typeOfData: FileDataForML.thumbnailData,
-    );
     final String? filePath =
         await _getImagePathForML(enteFile, typeOfData: FileDataForML.fileData);
 
-    if (thumbnailPath == null && filePath == null) {
+    if (filePath == null) {
       _logger.severe(
         "Failed to get any data for enteFile with uploadedFileID ${enteFile.uploadedFileID}",
       );
       throw CouldNotRetrieveAnyFileData();
     }
 
-    final String smallDataPath = thumbnailPath ?? filePath!;
-    final String largeDataPath = filePath ?? thumbnailPath!;
-
     final Stopwatch stopwatch = Stopwatch()..start();
     late FaceMlResult result;
 
@@ -747,8 +741,7 @@ class FaceMlService {
           FaceMlOperation.analyzeImage,
           {
             "enteFileID": enteFile.uploadedFileID ?? -1,
-            "smallDataPath": smallDataPath,
-            "largeDataPath": largeDataPath,
+            "filePath": filePath,
             "faceDetectionAddress":
                 YoloOnnxFaceDetection.instance.sessionAddress,
             "faceEmbeddingAddress": FaceEmbeddingOnnx.instance.sessionAddress,

+ 1 - 2
mobile/lib/utils/image_ml_util.dart

@@ -658,8 +658,7 @@ Future<(Num3DInputMatrix, Size, Size)> preprocessImageToMatrix(
   return (imageMatrix, originalSize, newSize);
 }
 
-Future<(Float32List, Size, Size)>
-    preprocessImageToFloat32ChannelsFirst(
+Future<(Float32List, Size, Size)> preprocessImageToFloat32ChannelsFirst(
   Uint8List imageData, {
   required int normalization,
   required int requiredWidth,