diff --git a/mobile/lib/services/machine_learning/face_ml/face_ml_service.dart b/mobile/lib/services/machine_learning/face_ml/face_ml_service.dart index 7c742d033..a65e137d2 100644 --- a/mobile/lib/services/machine_learning/face_ml/face_ml_service.dart +++ b/mobile/lib/services/machine_learning/face_ml/face_ml_service.dart @@ -9,7 +9,6 @@ import "dart:ui" show Image; import "package:computer/computer.dart"; import "package:dart_ui_isolate/dart_ui_isolate.dart"; import "package:flutter/foundation.dart" show debugPrint, kDebugMode; -import "package:flutter_image_compress/flutter_image_compress.dart"; import "package:logging/logging.dart"; import "package:onnxruntime/onnxruntime.dart"; import "package:package_info_plus/package_info_plus.dart"; @@ -326,12 +325,12 @@ class FaceMlService { _logger.info( 'Clustering Isolate has been inactive for ${_inactivityDuration.inSeconds} seconds with no tasks running. Killing isolate.', ); - disposeIsolate(); + _disposeIsolate(); } }); } - void disposeIsolate() async { + void _disposeIsolate() async { if (!_isIsolateSpawned) return; await release(); @@ -750,7 +749,7 @@ class FaceMlService { ); try { - final FaceMlResult? result = await analyzeImageInSingleIsolate( + final FaceMlResult? result = await _analyzeImageInSingleIsolate( enteFile, // preferUsingThumbnailForEverything: false, // disposeImageIsolateAfterUse: false, @@ -843,7 +842,7 @@ class FaceMlService { } /// Analyzes the given image data by running the full pipeline for faces, using [analyzeImageSync] in the isolate. - Future analyzeImageInSingleIsolate(EnteFile enteFile) async { + Future _analyzeImageInSingleIsolate(EnteFile enteFile) async { _checkEnteFileForID(enteFile); await ensureInitialized(); @@ -1034,94 +1033,6 @@ class FaceMlService { return imagePath; } - @Deprecated('Deprecated in favor of `_getImagePathForML`') - Future _getDataForML( - EnteFile enteFile, { - FileDataForML typeOfData = FileDataForML.fileData, - }) async { - Uint8List? data; - - switch (typeOfData) { - case FileDataForML.fileData: - final stopwatch = Stopwatch()..start(); - final File? actualIoFile = await getFile(enteFile, isOrigin: true); - if (actualIoFile != null) { - data = await actualIoFile.readAsBytes(); - } - stopwatch.stop(); - _logger.info( - "Getting file data for uploadedFileID ${enteFile.uploadedFileID} took ${stopwatch.elapsedMilliseconds} ms", - ); - - break; - - case FileDataForML.thumbnailData: - final stopwatch = Stopwatch()..start(); - data = await getThumbnail(enteFile); - stopwatch.stop(); - _logger.info( - "Getting thumbnail data for uploadedFileID ${enteFile.uploadedFileID} took ${stopwatch.elapsedMilliseconds} ms", - ); - break; - - case FileDataForML.compressedFileData: - final stopwatch = Stopwatch()..start(); - final String tempPath = Configuration.instance.getTempDirectory() + - "${enteFile.uploadedFileID!}"; - final File? actualIoFile = await getFile(enteFile); - if (actualIoFile != null) { - final compressResult = await FlutterImageCompress.compressAndGetFile( - actualIoFile.path, - tempPath + ".jpg", - ); - if (compressResult != null) { - data = await compressResult.readAsBytes(); - } - } - stopwatch.stop(); - _logger.info( - "Getting compressed file data for uploadedFileID ${enteFile.uploadedFileID} took ${stopwatch.elapsedMilliseconds} ms", - ); - break; - } - - return data; - } - - /// Detects faces in the given image data. - /// - /// `imageData`: The image data to analyze. - /// - /// Returns a list of face detection results. - /// - /// Throws [CouldNotInitializeFaceDetector], [CouldNotRunFaceDetector] or [GeneralFaceMlException] if something goes wrong. - Future> _detectFacesIsolate( - String imagePath, - // Uint8List fileData, - { - FaceMlResultBuilder? resultBuilder, - }) async { - try { - // Get the bounding boxes of the faces - final (List faces, dataSize) = - await FaceDetectionService.instance.predictInComputer(imagePath); - - // Add detected faces to the resultBuilder - if (resultBuilder != null) { - resultBuilder.addNewlyDetectedFaces(faces, dataSize); - } - - return faces; - } on YOLOFaceInterpreterInitializationException { - throw CouldNotInitializeFaceDetector(); - } on YOLOFaceInterpreterRunException { - throw CouldNotRunFaceDetector(); - } catch (e) { - _logger.severe('Face detection failed: $e'); - throw GeneralFaceMlException('Face detection failed: $e'); - } - } - /// Detects faces in the given image data. /// /// `imageData`: The image data to analyze. @@ -1160,38 +1071,6 @@ class FaceMlService { } } - /// Aligns multiple faces from the given image data. - /// - /// `imageData`: The image data in [Uint8List] that contains the faces. - /// `faces`: The face detection results in a list of [FaceDetectionAbsolute] for the faces to align. - /// - /// Returns a list of the aligned faces as image data. - /// - /// Throws [CouldNotWarpAffine] or [GeneralFaceMlException] if the face alignment fails. - Future _alignFaces( - String imagePath, - List faces, { - FaceMlResultBuilder? resultBuilder, - }) async { - try { - final (alignedFaces, alignmentResults, _, blurValues, _) = - await ImageMlIsolate.instance - .preprocessMobileFaceNetOnnx(imagePath, faces); - - if (resultBuilder != null) { - resultBuilder.addAlignmentResults( - alignmentResults, - blurValues, - ); - } - - return alignedFaces; - } catch (e, s) { - _logger.severe('Face alignment failed: $e', e, s); - throw CouldNotWarpAffine(); - } - } - /// Aligns multiple faces from the given image data. /// /// `imageData`: The image data in [Uint8List] that contains the faces. @@ -1233,45 +1112,6 @@ class FaceMlService { } } - /// Embeds multiple faces from the given input matrices. - /// - /// `facesMatrices`: The input matrices of the faces to embed. - /// - /// Returns a list of the face embeddings as lists of doubles. - /// - /// Throws [CouldNotInitializeFaceEmbeddor], [CouldNotRunFaceEmbeddor], [InputProblemFaceEmbeddor] or [GeneralFaceMlException] if the face embedding fails. - Future>> _embedFaces( - Float32List facesList, { - FaceMlResultBuilder? resultBuilder, - }) async { - try { - // Get the embedding of the faces - final List> embeddings = - await FaceEmbeddingService.instance.predictInComputer(facesList); - - // Add the embeddings to the resultBuilder - if (resultBuilder != null) { - resultBuilder.addEmbeddingsToExistingFaces(embeddings); - } - - return embeddings; - } on MobileFaceNetInterpreterInitializationException { - throw CouldNotInitializeFaceEmbeddor(); - } on MobileFaceNetInterpreterRunException { - throw CouldNotRunFaceEmbeddor(); - } on MobileFaceNetEmptyInput { - throw InputProblemFaceEmbeddor("Input is empty"); - } on MobileFaceNetWrongInputSize { - throw InputProblemFaceEmbeddor("Input size is wrong"); - } on MobileFaceNetWrongInputRange { - throw InputProblemFaceEmbeddor("Input range is wrong"); - // ignore: avoid_catches_without_on_clauses - } catch (e) { - _logger.severe('Face embedding (batch) failed: $e'); - throw GeneralFaceMlException('Face embedding (batch) failed: $e'); - } - } - static Future>> embedFacesSync( Float32List facesList, int interpreterAddress, { @@ -1311,10 +1151,9 @@ class FaceMlService { _logger.warning( '''Skipped analysis of image with enteFile, it might be the wrong format or has no uploadedFileID, or MLController doesn't allow it to run. enteFile: ${enteFile.toString()} - isImageIndexRunning: $_isIndexingOrClusteringRunning - canRunML: $_mlControllerStatus ''', ); + _logStatus(); throw CouldNotRetrieveAnyFileData(); } }