diff --git a/lib/main.dart b/lib/main.dart index 4548871ab..51fb7b9d6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -24,6 +24,7 @@ import 'package:photos/services/local_file_update_service.dart'; import 'package:photos/services/local_sync_service.dart'; import 'package:photos/services/memories_service.dart'; import 'package:photos/services/notification_service.dart'; +import "package:photos/services/object_detection/object_detection_service.dart"; import 'package:photos/services/push_service.dart'; import 'package:photos/services/remote_sync_service.dart'; import 'package:photos/services/search_service.dart'; @@ -160,6 +161,7 @@ Future _init(bool isBackground, {String via = ''}) async { }); } FeatureFlagService.instance.init(); + await ObjectDetectionService.instance.init(); _logger.info("Initialization done"); } diff --git a/lib/services/object_detection/object_detection_service.dart b/lib/services/object_detection/object_detection_service.dart new file mode 100644 index 000000000..47294be1e --- /dev/null +++ b/lib/services/object_detection/object_detection_service.dart @@ -0,0 +1,57 @@ +import "dart:isolate"; +import "dart:typed_data"; + +import "package:logging/logging.dart"; +import "package:photos/services/object_detection/models/predictions.dart"; +import 'package:photos/services/object_detection/models/recognition.dart'; +import "package:photos/services/object_detection/tflite/classifier.dart"; +import "package:photos/services/object_detection/utils/isolate_utils.dart"; + +class ObjectDetectionService { + final _logger = Logger("ObjectDetectionService"); + + /// Instance of [ObjectClassifier] + late ObjectClassifier _classifier; + + /// Instance of [IsolateUtils] + late IsolateUtils _isolateUtils; + + ObjectDetectionService._privateConstructor(); + + Future init() async { + _isolateUtils = IsolateUtils(); + await _isolateUtils.start(); + _classifier = ObjectClassifier(); + } + + static ObjectDetectionService instance = + ObjectDetectionService._privateConstructor(); + + Future> predict(Uint8List bytes) async { + try { + final isolateData = IsolateData( + bytes, + _classifier.interpreter.address, + _classifier.labels, + ); + final predictions = await _inference(isolateData); + final Set results = {}; + for (final Recognition result in predictions.recognitions) { + results.add(result.label); + } + return results.toList(); + } catch (e, s) { + _logger.severe(e, s); + rethrow; + } + } + + /// Runs inference in another isolate + Future _inference(IsolateData isolateData) async { + final responsePort = ReceivePort(); + _isolateUtils.sendPort.send( + isolateData..responsePort = responsePort.sendPort, + ); + return await responsePort.first; + } +}