Hello ducky (#1382)

This commit is contained in:
Ashil 2023-09-09 10:34:42 +05:30 committed by GitHub
commit 271eb98ce5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
98 changed files with 651 additions and 695 deletions

View file

@ -3,7 +3,7 @@
package="io.ente.photos">
<application android:name="${applicationName}"
android:label="@string/app_name"
android:icon="@mipmap/launcher_icon"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
android:allowBackup="false"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 69 B

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground>
<inset
android:drawable="@drawable/ic_launcher_foreground"
android:inset="26%" />
</foreground>
</adaptive-icon>

View file

@ -2,5 +2,4 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -4,6 +4,7 @@
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#000000</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>

View file

@ -7,6 +7,7 @@
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.

View file

@ -4,6 +4,7 @@
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#ffffff</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>

BIN
assets/ente.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
assets/splash-icon-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1,8 +1,6 @@
PODS:
- background_fetch (1.1.6):
- Flutter
- camera_avfoundation (0.0.1):
- Flutter
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
@ -165,8 +163,6 @@ PODS:
- FMDB (>= 2.7.5)
- tflite_flutter (0.1.0):
- Flutter
- tflite_flutter_helper (0.0.1):
- Flutter
- Toast (4.0.0)
- uni_links (0.0.1):
- Flutter
@ -182,7 +178,6 @@ PODS:
DEPENDENCIES:
- background_fetch (from `.symlinks/plugins/background_fetch/ios`)
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- device_info (from `.symlinks/plugins/device_info/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
@ -214,7 +209,6 @@ DEPENDENCIES:
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- tflite_flutter (from `.symlinks/plugins/tflite_flutter/ios`)
- tflite_flutter_helper (from `.symlinks/plugins/tflite_flutter_helper/ios`)
- uni_links (from `.symlinks/plugins/uni_links/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
@ -246,8 +240,6 @@ SPEC REPOS:
EXTERNAL SOURCES:
background_fetch:
:path: ".symlinks/plugins/background_fetch/ios"
camera_avfoundation:
:path: ".symlinks/plugins/camera_avfoundation/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
device_info:
@ -310,8 +302,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite/ios"
tflite_flutter:
:path: ".symlinks/plugins/tflite_flutter/ios"
tflite_flutter_helper:
:path: ".symlinks/plugins/tflite_flutter_helper/ios"
uni_links:
:path: ".symlinks/plugins/uni_links/ios"
url_launcher_ios:
@ -325,7 +315,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
background_fetch: bc9b44b0bf8b434e282a2ac9be8662800a0296ed
camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
connectivity_plus: 53efb943fc2882c8512d84c45707bcabc4c36076
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
Firebase: bd152f0f3d278c4060c5c71359db08ebcfd5a3e2
@ -375,7 +364,6 @@ SPEC CHECKSUMS:
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
tflite_flutter: 9157a660578930a99728974f247369af1c3595d5
tflite_flutter_helper: 543b46b6bd064b21c92ea6e54bc0b29f1ce74cb5
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4

View file

@ -276,7 +276,6 @@
"${BUILT_PRODUCTS_DIR}/SentryPrivate/SentryPrivate.framework",
"${BUILT_PRODUCTS_DIR}/Toast/Toast.framework",
"${BUILT_PRODUCTS_DIR}/background_fetch/background_fetch.framework",
"${BUILT_PRODUCTS_DIR}/camera_avfoundation/camera_avfoundation.framework",
"${BUILT_PRODUCTS_DIR}/connectivity_plus/connectivity_plus.framework",
"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
"${BUILT_PRODUCTS_DIR}/fk_user_agent/fk_user_agent.framework",
@ -307,7 +306,6 @@
"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
"${BUILT_PRODUCTS_DIR}/tflite_flutter/tflite_flutter.framework",
"${BUILT_PRODUCTS_DIR}/tflite_flutter_helper/tflite_flutter_helper.framework",
"${BUILT_PRODUCTS_DIR}/uni_links/uni_links.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
"${BUILT_PRODUCTS_DIR}/video_player_avfoundation/video_player_avfoundation.framework",
@ -333,7 +331,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SentryPrivate.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Toast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/background_fetch.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/camera_avfoundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fk_user_agent.framework",
@ -364,7 +361,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tflite_flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/tflite_flutter_helper.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/uni_links.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/video_player_avfoundation.framework",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -64,10 +64,10 @@
</dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>FLTEnableImpeller</key>
<false />
<key>FLTEnableWideGamut</key>
<false/>
<key>FLTEnableImpeller</key>
<false/>
<key>FLTEnableWideGamut</key>
<false/>
<key>NSFaceIDUsageDescription</key>
<string>Please allow ente to lock itself with FaceID or TouchID</string>
<key>NSCameraUsageDescription</key>

View file

@ -29,7 +29,7 @@ import 'package:photos/services/local_file_update_service.dart';
import 'package:photos/services/local_sync_service.dart';
import "package:photos/services/location_service.dart";
import 'package:photos/services/memories_service.dart';
import "package:photos/services/object_detection/object_detection_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';
@ -190,9 +190,9 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
// Can not including existing tf/ml binaries as they are not being built
// from source.
// See https://gitlab.com/fdroid/fdroiddata/-/merge_requests/12671#note_1294346819
if (!UpdateService.instance.isFdroidFlavor()) {
unawaited(ObjectDetectionService.instance.init());
}
// if (!UpdateService.instance.isFdroidFlavor()) {
// unawaited(ObjectDetectionService.instance.init());
// }
_logger.info("Initialization done");
}

View file

@ -1,157 +1,157 @@
import "dart:isolate";
import "dart:math";
import "dart:typed_data";
// import "dart:isolate";
// import "dart:math";
// 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/cocossd_classifier.dart';
import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
import "package:photos/services/object_detection/tflite/scene_classifier.dart";
import "package:photos/services/object_detection/utils/isolate_utils.dart";
// 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/cocossd_classifier.dart';
// import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
// import "package:photos/services/object_detection/tflite/scene_classifier.dart";
// import "package:photos/services/object_detection/utils/isolate_utils.dart";
class ObjectDetectionService {
static const scoreThreshold = 0.35;
// class ObjectDetectionService {
// static const scoreThreshold = 0.35;
final _logger = Logger("ObjectDetectionService");
// final _logger = Logger("ObjectDetectionService");
late CocoSSDClassifier _objectClassifier;
late MobileNetClassifier _mobileNetClassifier;
late SceneClassifier _sceneClassifier;
// late CocoSSDClassifier _objectClassifier;
// late MobileNetClassifier _mobileNetClassifier;
// late SceneClassifier _sceneClassifier;
late IsolateUtils _isolateUtils;
// late IsolateUtils _isolateUtils;
ObjectDetectionService._privateConstructor();
bool inInitiated = false;
// ObjectDetectionService._privateConstructor();
// bool inInitiated = false;
Future<void> init() async {
_isolateUtils = IsolateUtils();
await _isolateUtils.start();
try {
_objectClassifier = CocoSSDClassifier();
} catch (e, s) {
_logger.severe("Could not initialize cocossd", e, s);
}
try {
_mobileNetClassifier = MobileNetClassifier();
} catch (e, s) {
_logger.severe("Could not initialize mobilenet", e, s);
}
try {
_sceneClassifier = SceneClassifier();
} catch (e, s) {
_logger.severe("Could not initialize sceneclassifier", e, s);
}
inInitiated = true;
}
// Future<void> init() async {
// _isolateUtils = IsolateUtils();
// await _isolateUtils.start();
// try {
// _objectClassifier = CocoSSDClassifier();
// } catch (e, s) {
// _logger.severe("Could not initialize cocossd", e, s);
// }
// try {
// _mobileNetClassifier = MobileNetClassifier();
// } catch (e, s) {
// _logger.severe("Could not initialize mobilenet", e, s);
// }
// try {
// _sceneClassifier = SceneClassifier();
// } catch (e, s) {
// _logger.severe("Could not initialize sceneclassifier", e, s);
// }
// inInitiated = true;
// }
static ObjectDetectionService instance =
ObjectDetectionService._privateConstructor();
// static ObjectDetectionService instance =
// ObjectDetectionService._privateConstructor();
Future<Map<String, double>> predict(Uint8List bytes) async {
try {
if (!inInitiated) {
return Future.error("ObjectDetectionService init is not completed");
}
final results = <String, double>{};
final methods = [_getObjects, _getMobileNetResults, _getSceneResults];
// Future<Map<String, double>> predict(Uint8List bytes) async {
// try {
// if (!inInitiated) {
// return Future.error("ObjectDetectionService init is not completed");
// }
// final results = <String, double>{};
// final methods = [_getObjects, _getMobileNetResults, _getSceneResults];
for (var method in methods) {
final methodResults = await method(bytes);
methodResults.forEach((key, value) {
results.update(
key,
(existingValue) => max(existingValue, value),
ifAbsent: () => value,
);
});
}
return results;
} catch (e, s) {
_logger.severe(e, s);
rethrow;
}
}
// for (var method in methods) {
// final methodResults = await method(bytes);
// methodResults.forEach((key, value) {
// results.update(
// key,
// (existingValue) => max(existingValue, value),
// ifAbsent: () => value,
// );
// });
// }
// return results;
// } catch (e, s) {
// _logger.severe(e, s);
// rethrow;
// }
// }
Future<Map<String, double>> _getObjects(Uint8List bytes) async {
try {
final isolateData = IsolateData(
bytes,
_objectClassifier.interpreter.address,
_objectClassifier.labels,
ClassifierType.cocossd,
);
return _getPredictions(isolateData);
} catch (e, s) {
_logger.severe("Could not run cocossd", e, s);
}
return {};
}
// Future<Map<String, double>> _getObjects(Uint8List bytes) async {
// try {
// final isolateData = IsolateData(
// bytes,
// _objectClassifier.interpreter.address,
// _objectClassifier.labels,
// ClassifierType.cocossd,
// );
// return _getPredictions(isolateData);
// } catch (e, s) {
// _logger.severe("Could not run cocossd", e, s);
// }
// return {};
// }
Future<Map<String, double>> _getMobileNetResults(Uint8List bytes) async {
try {
final isolateData = IsolateData(
bytes,
_mobileNetClassifier.interpreter.address,
_mobileNetClassifier.labels,
ClassifierType.mobilenet,
);
return _getPredictions(isolateData);
} catch (e, s) {
_logger.severe("Could not run mobilenet", e, s);
}
return {};
}
// Future<Map<String, double>> _getMobileNetResults(Uint8List bytes) async {
// try {
// final isolateData = IsolateData(
// bytes,
// _mobileNetClassifier.interpreter.address,
// _mobileNetClassifier.labels,
// ClassifierType.mobilenet,
// );
// return _getPredictions(isolateData);
// } catch (e, s) {
// _logger.severe("Could not run mobilenet", e, s);
// }
// return {};
// }
Future<Map<String, double>> _getSceneResults(Uint8List bytes) async {
try {
final isolateData = IsolateData(
bytes,
_sceneClassifier.interpreter.address,
_sceneClassifier.labels,
ClassifierType.scenes,
);
return _getPredictions(isolateData);
} catch (e, s) {
_logger.severe("Could not run scene detection", e, s);
}
return {};
}
// Future<Map<String, double>> _getSceneResults(Uint8List bytes) async {
// try {
// final isolateData = IsolateData(
// bytes,
// _sceneClassifier.interpreter.address,
// _sceneClassifier.labels,
// ClassifierType.scenes,
// );
// return _getPredictions(isolateData);
// } catch (e, s) {
// _logger.severe("Could not run scene detection", e, s);
// }
// return {};
// }
Future<Map<String, double>> _getPredictions(IsolateData isolateData) async {
final predictions = await _inference(isolateData);
final Map<String, double> results = {};
// Future<Map<String, double>> _getPredictions(IsolateData isolateData) async {
// final predictions = await _inference(isolateData);
// final Map<String, double> results = {};
if (predictions.error == null) {
for (final Recognition result in predictions.recognitions!) {
if (result.score > scoreThreshold) {
// Update the result score only if it's higher than the current score
if (!results.containsKey(result.label) ||
results[result.label]! < result.score) {
results[result.label] = result.score;
}
}
}
// if (predictions.error == null) {
// for (final Recognition result in predictions.recognitions!) {
// if (result.score > scoreThreshold) {
// // Update the result score only if it's higher than the current score
// if (!results.containsKey(result.label) ||
// results[result.label]! < result.score) {
// results[result.label] = result.score;
// }
// }
// }
_logger.info(
"Time taken for ${isolateData.type}: ${predictions.stats!.totalElapsedTime}ms",
);
} else {
_logger.severe(
"Error while fetching predictions for ${isolateData.type}",
predictions.error,
);
}
// _logger.info(
// "Time taken for ${isolateData.type}: ${predictions.stats!.totalElapsedTime}ms",
// );
// } else {
// _logger.severe(
// "Error while fetching predictions for ${isolateData.type}",
// predictions.error,
// );
// }
return results;
}
// return results;
// }
/// Runs inference in another isolate
Future<Predictions> _inference(IsolateData isolateData) async {
final responsePort = ReceivePort();
_isolateUtils.sendPort.send(
isolateData..responsePort = responsePort.sendPort,
);
return await responsePort.first;
}
}
// /// Runs inference in another isolate
// Future<Predictions> _inference(IsolateData isolateData) async {
// final responsePort = ReceivePort();
// _isolateUtils.sendPort.send(
// isolateData..responsePort = responsePort.sendPort,
// );
// return await responsePort.first;
// }
// }

View file

@ -1,89 +1,89 @@
import "dart:math";
// import "dart:math";
import 'package:image/image.dart' as image_lib;
import "package:logging/logging.dart";
import "package:photos/services/object_detection/models/predictions.dart";
import "package:tflite_flutter/tflite_flutter.dart";
import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
// import 'package:image/image.dart' as image_lib;
// import "package:logging/logging.dart";
// import "package:photos/services/object_detection/models/predictions.dart";
// import "package:tflite_flutter/tflite_flutter.dart";
// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
abstract class Classifier {
// Path to the model
String get modelPath;
// abstract class Classifier {
// // Path to the model
// String get modelPath;
// Path to the labels
String get labelPath;
// // Path to the labels
// String get labelPath;
// Input size expected by the model (for eg. width = height = 224)
int get inputSize;
// // Input size expected by the model (for eg. width = height = 224)
// int get inputSize;
// Logger implementation for the specific classifier
Logger get logger;
// // Logger implementation for the specific classifier
// Logger get logger;
Predictions? predict(image_lib.Image image);
// Predictions? predict(image_lib.Image image);
/// Instance of Interpreter
late Interpreter _interpreter;
// /// Instance of Interpreter
// late Interpreter _interpreter;
/// Labels file loaded as list
late List<String> _labels;
// /// Labels file loaded as list
// late List<String> _labels;
/// Shapes of output tensors
late List<List<int>> _outputShapes;
// /// Shapes of output tensors
// late List<List<int>> _outputShapes;
/// Types of output tensors
late List<TfLiteType> _outputTypes;
// /// Types of output tensors
// late List<TfLiteType> _outputTypes;
/// Gets the interpreter instance
Interpreter get interpreter => _interpreter;
// /// Gets the interpreter instance
// Interpreter get interpreter => _interpreter;
/// Gets the loaded labels
List<String> get labels => _labels;
// /// Gets the loaded labels
// List<String> get labels => _labels;
/// Gets the output shapes
List<List<int>> get outputShapes => _outputShapes;
// /// Gets the output shapes
// List<List<int>> get outputShapes => _outputShapes;
/// Gets the output types
List<TfLiteType> get outputTypes => _outputTypes;
// /// Gets the output types
// List<TfLiteType> get outputTypes => _outputTypes;
/// Loads interpreter from asset
void loadModel(Interpreter? interpreter) async {
try {
_interpreter = interpreter ??
await Interpreter.fromAsset(
modelPath,
options: InterpreterOptions()..threads = 4,
);
final outputTensors = _interpreter.getOutputTensors();
_outputShapes = [];
_outputTypes = [];
for (var tensor in outputTensors) {
_outputShapes.add(tensor.shape);
_outputTypes.add(tensor.type);
}
logger.info("Interpreter initialized");
} catch (e, s) {
logger.severe("Error while creating interpreter", e, s);
}
}
// /// Loads interpreter from asset
// void loadModel(Interpreter? interpreter) async {
// try {
// _interpreter = interpreter ??
// await Interpreter.fromAsset(
// modelPath,
// options: InterpreterOptions()..threads = 4,
// );
// final outputTensors = _interpreter.getOutputTensors();
// _outputShapes = [];
// _outputTypes = [];
// for (var tensor in outputTensors) {
// _outputShapes.add(tensor.shape);
// _outputTypes.add(tensor.type);
// }
// logger.info("Interpreter initialized");
// } catch (e, s) {
// logger.severe("Error while creating interpreter", e, s);
// }
// }
/// Loads labels from assets
void loadLabels(List<String>? labels) async {
try {
_labels = labels ?? await FileUtil.loadLabels(labelPath);
logger.info("Labels initialized");
} catch (e, s) {
logger.severe("Error while loading labels", e, s);
}
}
// /// Loads labels from assets
// void loadLabels(List<String>? labels) async {
// try {
// _labels = labels ?? await FileUtil.loadLabels(labelPath);
// logger.info("Labels initialized");
// } catch (e, s) {
// logger.severe("Error while loading labels", e, s);
// }
// }
/// Pre-process the image
TensorImage getProcessedImage(TensorImage inputImage) {
final padSize = max(inputImage.height, inputImage.width);
final imageProcessor = ImageProcessorBuilder()
.add(ResizeWithCropOrPadOp(padSize, padSize))
.add(ResizeOp(inputSize, inputSize, ResizeMethod.BILINEAR))
.build();
inputImage = imageProcessor.process(inputImage);
return inputImage;
}
}
// /// Pre-process the image
// TensorImage getProcessedImage(TensorImage inputImage) {
// final padSize = max(inputImage.height, inputImage.width);
// final imageProcessor = ImageProcessorBuilder()
// .add(ResizeWithCropOrPadOp(padSize, padSize))
// .add(ResizeOp(inputSize, inputSize, ResizeMethod.BILINEAR))
// .build();
// inputImage = imageProcessor.process(inputImage);
// return inputImage;
// }
// }

View file

@ -1,115 +1,115 @@
import 'dart:math';
// import 'dart:math';
import 'package:image/image.dart' as image_lib;
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/models/stats.dart";
import "package:photos/services/object_detection/tflite/classifier.dart";
import "package:tflite_flutter/tflite_flutter.dart";
import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
// import 'package:image/image.dart' as image_lib;
// 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/models/stats.dart";
// import "package:photos/services/object_detection/tflite/classifier.dart";
// import "package:tflite_flutter/tflite_flutter.dart";
// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
/// Classifier
class CocoSSDClassifier extends Classifier {
static final _logger = Logger("CocoSSDClassifier");
static const double threshold = 0.4;
// /// Classifier
// class CocoSSDClassifier extends Classifier {
// static final _logger = Logger("CocoSSDClassifier");
// static const double threshold = 0.4;
@override
String get modelPath => "models/cocossd/model.tflite";
// @override
// String get modelPath => "models/cocossd/model.tflite";
@override
String get labelPath => "assets/models/cocossd/labels.txt";
// @override
// String get labelPath => "assets/models/cocossd/labels.txt";
@override
int get inputSize => 300;
// @override
// int get inputSize => 300;
@override
Logger get logger => _logger;
// @override
// Logger get logger => _logger;
static const int numResults = 10;
// static const int numResults = 10;
CocoSSDClassifier({
Interpreter? interpreter,
List<String>? labels,
}) {
loadModel(interpreter);
loadLabels(labels);
}
// CocoSSDClassifier({
// Interpreter? interpreter,
// List<String>? labels,
// }) {
// loadModel(interpreter);
// loadLabels(labels);
// }
@override
Predictions? predict(image_lib.Image image) {
final predictStartTime = DateTime.now().millisecondsSinceEpoch;
// @override
// Predictions? predict(image_lib.Image image) {
// final predictStartTime = DateTime.now().millisecondsSinceEpoch;
final preProcessStart = DateTime.now().millisecondsSinceEpoch;
// final preProcessStart = DateTime.now().millisecondsSinceEpoch;
// Create TensorImage from image
TensorImage inputImage = TensorImage.fromImage(image);
// // Create TensorImage from image
// TensorImage inputImage = TensorImage.fromImage(image);
// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);
// // Pre-process TensorImage
// inputImage = getProcessedImage(inputImage);
final preProcessElapsedTime =
DateTime.now().millisecondsSinceEpoch - preProcessStart;
// final preProcessElapsedTime =
// DateTime.now().millisecondsSinceEpoch - preProcessStart;
// TensorBuffers for output tensors
final outputLocations = TensorBufferFloat(outputShapes[0]);
final outputClasses = TensorBufferFloat(outputShapes[1]);
final outputScores = TensorBufferFloat(outputShapes[2]);
final numLocations = TensorBufferFloat(outputShapes[3]);
// // TensorBuffers for output tensors
// final outputLocations = TensorBufferFloat(outputShapes[0]);
// final outputClasses = TensorBufferFloat(outputShapes[1]);
// final outputScores = TensorBufferFloat(outputShapes[2]);
// final numLocations = TensorBufferFloat(outputShapes[3]);
// Inputs object for runForMultipleInputs
// Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
final inputs = [inputImage.buffer];
// // Inputs object for runForMultipleInputs
// // Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
// final inputs = [inputImage.buffer];
// Outputs map
final outputs = {
0: outputLocations.buffer,
1: outputClasses.buffer,
2: outputScores.buffer,
3: numLocations.buffer,
};
// // Outputs map
// final outputs = {
// 0: outputLocations.buffer,
// 1: outputClasses.buffer,
// 2: outputScores.buffer,
// 3: numLocations.buffer,
// };
final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
// final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
// run inference
interpreter.runForMultipleInputs(inputs, outputs);
// // run inference
// interpreter.runForMultipleInputs(inputs, outputs);
final inferenceTimeElapsed =
DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
// final inferenceTimeElapsed =
// DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
// Maximum number of results to show
final resultsCount = min(numResults, numLocations.getIntValue(0));
// // Maximum number of results to show
// final resultsCount = min(numResults, numLocations.getIntValue(0));
// Using labelOffset = 1 as ??? at index 0
const labelOffset = 1;
// // Using labelOffset = 1 as ??? at index 0
// const labelOffset = 1;
final recognitions = <Recognition>[];
// final recognitions = <Recognition>[];
for (int i = 0; i < resultsCount; i++) {
// Prediction score
final score = outputScores.getDoubleValue(i);
// for (int i = 0; i < resultsCount; i++) {
// // Prediction score
// final score = outputScores.getDoubleValue(i);
// Label string
final labelIndex = outputClasses.getIntValue(i) + labelOffset;
final label = labels.elementAt(labelIndex);
// // Label string
// final labelIndex = outputClasses.getIntValue(i) + labelOffset;
// final label = labels.elementAt(labelIndex);
if (score > threshold) {
recognitions.add(
Recognition(i, label, score),
);
}
}
// if (score > threshold) {
// recognitions.add(
// Recognition(i, label, score),
// );
// }
// }
final predictElapsedTime =
DateTime.now().millisecondsSinceEpoch - predictStartTime;
return Predictions(
recognitions,
Stats(
predictElapsedTime,
predictElapsedTime,
inferenceTimeElapsed,
preProcessElapsedTime,
),
);
}
}
// final predictElapsedTime =
// DateTime.now().millisecondsSinceEpoch - predictStartTime;
// return Predictions(
// recognitions,
// Stats(
// predictElapsedTime,
// predictElapsedTime,
// inferenceTimeElapsed,
// preProcessElapsedTime,
// ),
// );
// }
// }

View file

@ -1,83 +1,83 @@
import 'package:image/image.dart' as image_lib;
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/models/stats.dart";
import "package:photos/services/object_detection/tflite/classifier.dart";
import "package:tflite_flutter/tflite_flutter.dart";
import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
// import 'package:image/image.dart' as image_lib;
// 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/models/stats.dart";
// import "package:photos/services/object_detection/tflite/classifier.dart";
// import "package:tflite_flutter/tflite_flutter.dart";
// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
// Source: https://tfhub.dev/tensorflow/lite-model/mobilenet_v1_1.0_224/1/default/1
class MobileNetClassifier extends Classifier {
static final _logger = Logger("MobileNetClassifier");
static const double threshold = 0.4;
// // Source: https://tfhub.dev/tensorflow/lite-model/mobilenet_v1_1.0_224/1/default/1
// class MobileNetClassifier extends Classifier {
// static final _logger = Logger("MobileNetClassifier");
// static const double threshold = 0.4;
@override
String get modelPath => "models/mobilenet/mobilenet_v1_1.0_224_quant.tflite";
// @override
// String get modelPath => "models/mobilenet/mobilenet_v1_1.0_224_quant.tflite";
@override
String get labelPath =>
"assets/models/mobilenet/labels_mobilenet_quant_v1_224.txt";
// @override
// String get labelPath =>
// "assets/models/mobilenet/labels_mobilenet_quant_v1_224.txt";
@override
int get inputSize => 224;
// @override
// int get inputSize => 224;
@override
Logger get logger => _logger;
// @override
// Logger get logger => _logger;
MobileNetClassifier({
Interpreter? interpreter,
List<String>? labels,
}) {
loadModel(interpreter);
loadLabels(labels);
}
// MobileNetClassifier({
// Interpreter? interpreter,
// List<String>? labels,
// }) {
// loadModel(interpreter);
// loadLabels(labels);
// }
@override
Predictions? predict(image_lib.Image image) {
final predictStartTime = DateTime.now().millisecondsSinceEpoch;
// @override
// Predictions? predict(image_lib.Image image) {
// final predictStartTime = DateTime.now().millisecondsSinceEpoch;
final preProcessStart = DateTime.now().millisecondsSinceEpoch;
// final preProcessStart = DateTime.now().millisecondsSinceEpoch;
// Create TensorImage from image
TensorImage inputImage = TensorImage.fromImage(image);
// // Create TensorImage from image
// TensorImage inputImage = TensorImage.fromImage(image);
// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);
// // Pre-process TensorImage
// inputImage = getProcessedImage(inputImage);
final preProcessElapsedTime =
DateTime.now().millisecondsSinceEpoch - preProcessStart;
// final preProcessElapsedTime =
// DateTime.now().millisecondsSinceEpoch - preProcessStart;
// TensorBuffers for output tensors
final output = TensorBufferUint8(outputShapes[0]);
final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
// run inference
interpreter.run(inputImage.buffer, output.buffer);
// // TensorBuffers for output tensors
// final output = TensorBufferUint8(outputShapes[0]);
// final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
// // run inference
// interpreter.run(inputImage.buffer, output.buffer);
final inferenceTimeElapsed =
DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
// final inferenceTimeElapsed =
// DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
final recognitions = <Recognition>[];
for (int i = 0; i < labels.length; i++) {
final score = output.getDoubleValue(i) / 255;
final label = labels.elementAt(i);
if (score >= threshold) {
recognitions.add(
Recognition(i, label, score),
);
}
}
// final recognitions = <Recognition>[];
// for (int i = 0; i < labels.length; i++) {
// final score = output.getDoubleValue(i) / 255;
// final label = labels.elementAt(i);
// if (score >= threshold) {
// recognitions.add(
// Recognition(i, label, score),
// );
// }
// }
final predictElapsedTime =
DateTime.now().millisecondsSinceEpoch - predictStartTime;
return Predictions(
recognitions,
Stats(
predictElapsedTime,
predictElapsedTime,
inferenceTimeElapsed,
preProcessElapsedTime,
),
);
}
}
// final predictElapsedTime =
// DateTime.now().millisecondsSinceEpoch - predictStartTime;
// return Predictions(
// recognitions,
// Stats(
// predictElapsedTime,
// predictElapsedTime,
// inferenceTimeElapsed,
// preProcessElapsedTime,
// ),
// );
// }
// }

View file

@ -1,88 +1,88 @@
import "package:flutter/foundation.dart";
import 'package:image/image.dart' as image_lib;
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/models/stats.dart";
import "package:photos/services/object_detection/tflite/classifier.dart";
import "package:tflite_flutter/tflite_flutter.dart";
import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
// import "package:flutter/foundation.dart";
// import 'package:image/image.dart' as image_lib;
// 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/models/stats.dart";
// import "package:photos/services/object_detection/tflite/classifier.dart";
// import "package:tflite_flutter/tflite_flutter.dart";
// import "package:tflite_flutter_helper/tflite_flutter_helper.dart";
// Source: https://tfhub.dev/sayannath/lite-model/image-scene/1
class SceneClassifier extends Classifier {
static final _logger = Logger("SceneClassifier");
static const double threshold = 0.35;
// // Source: https://tfhub.dev/sayannath/lite-model/image-scene/1
// class SceneClassifier extends Classifier {
// static final _logger = Logger("SceneClassifier");
// static const double threshold = 0.35;
@override
String get modelPath => "models/scenes/model.tflite";
// @override
// String get modelPath => "models/scenes/model.tflite";
@override
String get labelPath => "assets/models/scenes/labels.txt";
// @override
// String get labelPath => "assets/models/scenes/labels.txt";
@override
int get inputSize => 224;
// @override
// int get inputSize => 224;
@override
Logger get logger => _logger;
// @override
// Logger get logger => _logger;
SceneClassifier({
Interpreter? interpreter,
List<String>? labels,
}) {
loadModel(interpreter);
loadLabels(labels);
}
// SceneClassifier({
// Interpreter? interpreter,
// List<String>? labels,
// }) {
// loadModel(interpreter);
// loadLabels(labels);
// }
@override
Predictions? predict(image_lib.Image image) {
final predictStartTime = DateTime.now().millisecondsSinceEpoch;
// @override
// Predictions? predict(image_lib.Image image) {
// final predictStartTime = DateTime.now().millisecondsSinceEpoch;
final preProcessStart = DateTime.now().millisecondsSinceEpoch;
// final preProcessStart = DateTime.now().millisecondsSinceEpoch;
// Create TensorImage from image
TensorImage inputImage = TensorImage.fromImage(image);
// // Create TensorImage from image
// TensorImage inputImage = TensorImage.fromImage(image);
// Pre-process TensorImage
inputImage = getProcessedImage(inputImage);
final list = inputImage.getTensorBuffer().getDoubleList();
final input = list.reshape([1, inputSize, inputSize, 3]);
// // Pre-process TensorImage
// inputImage = getProcessedImage(inputImage);
// final list = inputImage.getTensorBuffer().getDoubleList();
// final input = list.reshape([1, inputSize, inputSize, 3]);
final preProcessElapsedTime =
DateTime.now().millisecondsSinceEpoch - preProcessStart;
// final preProcessElapsedTime =
// DateTime.now().millisecondsSinceEpoch - preProcessStart;
final output = TensorBufferFloat(outputShapes[0]);
// final output = TensorBufferFloat(outputShapes[0]);
final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
interpreter.run(input, output.buffer);
final inferenceTimeElapsed =
DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
// final inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
// interpreter.run(input, output.buffer);
// final inferenceTimeElapsed =
// DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
final recognitions = <Recognition>[];
for (int i = 0; i < labels.length; i++) {
final score = output.getDoubleValue(i);
final label = labels.elementAt(i);
if (score >= threshold) {
recognitions.add(
Recognition(i, label, score),
);
} else if (kDebugMode && score > 0.2) {
debugPrint("scenePrediction score $label is below threshold: $score");
}
}
debugPrint(
"Total lables ${labels.length} + reccg ${recognitions.map((e) => e.label).toSet()}",
);
// final recognitions = <Recognition>[];
// for (int i = 0; i < labels.length; i++) {
// final score = output.getDoubleValue(i);
// final label = labels.elementAt(i);
// if (score >= threshold) {
// recognitions.add(
// Recognition(i, label, score),
// );
// } else if (kDebugMode && score > 0.2) {
// debugPrint("scenePrediction score $label is below threshold: $score");
// }
// }
// debugPrint(
// "Total lables ${labels.length} + reccg ${recognitions.map((e) => e.label).toSet()}",
// );
final predictElapsedTime =
DateTime.now().millisecondsSinceEpoch - predictStartTime;
return Predictions(
recognitions,
Stats(
predictElapsedTime,
predictElapsedTime,
inferenceTimeElapsed,
preProcessElapsedTime,
),
);
}
}
// final predictElapsedTime =
// DateTime.now().millisecondsSinceEpoch - predictStartTime;
// return Predictions(
// recognitions,
// Stats(
// predictElapsedTime,
// predictElapsedTime,
// inferenceTimeElapsed,
// preProcessElapsedTime,
// ),
// );
// }
// }

View file

@ -1,88 +1,88 @@
import 'dart:isolate';
import "dart:typed_data";
// import 'dart:isolate';
// import "dart:typed_data";
import 'package:image/image.dart' as imgLib;
import "package:photos/services/object_detection/models/predictions.dart";
import "package:photos/services/object_detection/tflite/classifier.dart";
import 'package:photos/services/object_detection/tflite/cocossd_classifier.dart';
import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
import "package:photos/services/object_detection/tflite/scene_classifier.dart";
import 'package:tflite_flutter/tflite_flutter.dart';
// import 'package:image/image.dart' as imgLib;
// import "package:photos/services/object_detection/models/predictions.dart";
// import "package:photos/services/object_detection/tflite/classifier.dart";
// import 'package:photos/services/object_detection/tflite/cocossd_classifier.dart';
// import "package:photos/services/object_detection/tflite/mobilenet_classifier.dart";
// import "package:photos/services/object_detection/tflite/scene_classifier.dart";
// import 'package:tflite_flutter/tflite_flutter.dart';
/// Manages separate Isolate instance for inference
class IsolateUtils {
static const String debugName = "InferenceIsolate";
// /// Manages separate Isolate instance for inference
// class IsolateUtils {
// static const String debugName = "InferenceIsolate";
late SendPort _sendPort;
final _receivePort = ReceivePort();
// late SendPort _sendPort;
// final _receivePort = ReceivePort();
SendPort get sendPort => _sendPort;
// SendPort get sendPort => _sendPort;
Future<void> start() async {
await Isolate.spawn<SendPort>(
entryPoint,
_receivePort.sendPort,
debugName: debugName,
);
// Future<void> start() async {
// await Isolate.spawn<SendPort>(
// entryPoint,
// _receivePort.sendPort,
// debugName: debugName,
// );
_sendPort = await _receivePort.first;
}
// _sendPort = await _receivePort.first;
// }
static void entryPoint(SendPort sendPort) async {
final port = ReceivePort();
sendPort.send(port.sendPort);
// static void entryPoint(SendPort sendPort) async {
// final port = ReceivePort();
// sendPort.send(port.sendPort);
await for (final IsolateData isolateData in port) {
final classifier = _getClassifier(isolateData);
final image = imgLib.decodeImage(isolateData.input);
try {
final results = classifier.predict(image!);
isolateData.responsePort.send(results);
} catch (e) {
isolateData.responsePort.send(Predictions(null, null, error: e));
}
}
}
// await for (final IsolateData isolateData in port) {
// final classifier = _getClassifier(isolateData);
// final image = imgLib.decodeImage(isolateData.input);
// try {
// final results = classifier.predict(image!);
// isolateData.responsePort.send(results);
// } catch (e) {
// isolateData.responsePort.send(Predictions(null, null, error: e));
// }
// }
// }
static Classifier _getClassifier(IsolateData isolateData) {
final interpreter = Interpreter.fromAddress(isolateData.interpreterAddress);
if (isolateData.type == ClassifierType.cocossd) {
return CocoSSDClassifier(
interpreter: interpreter,
labels: isolateData.labels,
);
} else if (isolateData.type == ClassifierType.mobilenet) {
return MobileNetClassifier(
interpreter: interpreter,
labels: isolateData.labels,
);
} else {
return SceneClassifier(
interpreter: interpreter,
labels: isolateData.labels,
);
}
}
}
// static Classifier _getClassifier(IsolateData isolateData) {
// final interpreter = Interpreter.fromAddress(isolateData.interpreterAddress);
// if (isolateData.type == ClassifierType.cocossd) {
// return CocoSSDClassifier(
// interpreter: interpreter,
// labels: isolateData.labels,
// );
// } else if (isolateData.type == ClassifierType.mobilenet) {
// return MobileNetClassifier(
// interpreter: interpreter,
// labels: isolateData.labels,
// );
// } else {
// return SceneClassifier(
// interpreter: interpreter,
// labels: isolateData.labels,
// );
// }
// }
// }
/// Bundles data to pass between Isolate
class IsolateData {
Uint8List input;
int interpreterAddress;
List<String> labels;
ClassifierType type;
late SendPort responsePort;
// /// Bundles data to pass between Isolate
// class IsolateData {
// Uint8List input;
// int interpreterAddress;
// List<String> labels;
// ClassifierType type;
// late SendPort responsePort;
IsolateData(
this.input,
this.interpreterAddress,
this.labels,
this.type,
);
}
// IsolateData(
// this.input,
// this.interpreterAddress,
// this.labels,
// this.type,
// );
// }
enum ClassifierType {
cocossd,
mobilenet,
scenes,
}
// enum ClassifierType {
// cocossd,
// mobilenet,
// scenes,
// }

View file

@ -7,7 +7,7 @@ import 'package:photos/models/file/file.dart';
import 'package:photos/models/file/file_type.dart';
import "package:photos/models/metadata/file_magic.dart";
import "package:photos/services/file_magic_service.dart";
import "package:photos/services/update_service.dart";
// import "package:photos/services/update_service.dart";
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/buttons/icon_button_widget.dart';
import "package:photos/ui/components/divider_widget.dart";
@ -20,7 +20,7 @@ import "package:photos/ui/viewer/file_details/creation_time_item_widget.dart";
import 'package:photos/ui/viewer/file_details/exif_item_widgets.dart';
import "package:photos/ui/viewer/file_details/file_properties_item_widget.dart";
import "package:photos/ui/viewer/file_details/location_tags_widget.dart";
import "package:photos/ui/viewer/file_details/objects_item_widget.dart";
// import "package:photos/ui/viewer/file_details/objects_item_widget.dart";
import "package:photos/utils/exif_util.dart";
class FileDetailsWidget extends StatefulWidget {
@ -177,12 +177,12 @@ class _FileDetailsWidgetState extends State<FileDetailsWidget> {
]);
}
if (!UpdateService.instance.isFdroidFlavor()) {
fileDetailsTiles.addAll([
ObjectsItemWidget(file),
const FileDetailsDivider(),
]);
}
// if (!UpdateService.instance.isFdroidFlavor()) {
// fileDetailsTiles.addAll([
// ObjectsItemWidget(file),
// const FileDetailsDivider(),
// ]);
// }
if (file.uploadedFileID != null && file.updationTime != null) {
fileDetailsTiles.addAll(
@ -280,7 +280,8 @@ class _FileDetailsWidgetState extends State<FileDetailsWidget> {
if (imageWidth != null && imageLength != null) {
_exifData["resolution"] = '$imageWidth x $imageLength';
final double megaPixels =
(imageWidth.values.firstAsInt() * imageLength.values.firstAsInt()) / 1000000;
(imageWidth.values.firstAsInt() * imageLength.values.firstAsInt()) /
1000000;
final double roundedMegaPixels = (megaPixels * 10).round() / 10.0;
_exifData['megaPixels'] = roundedMegaPixels..toStringAsFixed(1);
} else {

View file

@ -1,67 +1,67 @@
import "package:flutter/foundation.dart";
import "package:flutter/material.dart";
import "package:logging/logging.dart";
import "package:photos/generated/l10n.dart";
import 'package:photos/models/file/file.dart';
import "package:photos/services/object_detection/object_detection_service.dart";
import "package:photos/ui/components/buttons/chip_button_widget.dart";
import "package:photos/ui/components/info_item_widget.dart";
import "package:photos/utils/thumbnail_util.dart";
// import "package:flutter/foundation.dart";
// import "package:flutter/material.dart";
// import "package:logging/logging.dart";
// import "package:photos/generated/l10n.dart";
// import 'package:photos/models/file/file.dart';
// import "package:photos/services/object_detection/object_detection_service.dart";
// import "package:photos/ui/components/buttons/chip_button_widget.dart";
// import "package:photos/ui/components/info_item_widget.dart";
// import "package:photos/utils/thumbnail_util.dart";
class ObjectsItemWidget extends StatelessWidget {
final EnteFile file;
const ObjectsItemWidget(this.file, {super.key});
// class ObjectsItemWidget extends StatelessWidget {
// final EnteFile file;
// const ObjectsItemWidget(this.file, {super.key});
@override
Widget build(BuildContext context) {
return InfoItemWidget(
key: const ValueKey("Objects"),
leadingIcon: Icons.image_search_outlined,
subtitleSection: _objectTags(context, file),
hasChipButtons: true,
);
}
// @override
// Widget build(BuildContext context) {
// return InfoItemWidget(
// key: const ValueKey("Objects"),
// leadingIcon: Icons.image_search_outlined,
// subtitleSection: _objectTags(context, file),
// hasChipButtons: true,
// );
// }
Future<List<ChipButtonWidget>> _objectTags(
BuildContext context,
EnteFile file,
) async {
try {
final chipButtons = <ChipButtonWidget>[];
var objectTags = <String, double>{};
final thumbnail = await getThumbnail(file);
if (thumbnail != null) {
objectTags = await ObjectDetectionService.instance.predict(thumbnail);
}
if (objectTags.isEmpty) {
return [
ChipButtonWidget(
S.of(context).noResults,
noChips: true,
),
];
}
// sort by values
objectTags = Map.fromEntries(
objectTags.entries.toList()
..sort((e1, e2) => e2.value.compareTo(e1.value)),
);
// Future<List<ChipButtonWidget>> _objectTags(
// BuildContext context,
// EnteFile file,
// ) async {
// try {
// final chipButtons = <ChipButtonWidget>[];
// var objectTags = <String, double>{};
// final thumbnail = await getThumbnail(file);
// if (thumbnail != null) {
// objectTags = await ObjectDetectionService.instance.predict(thumbnail);
// }
// if (objectTags.isEmpty) {
// return [
// ChipButtonWidget(
// S.of(context).noResults,
// noChips: true,
// ),
// ];
// }
// // sort by values
// objectTags = Map.fromEntries(
// objectTags.entries.toList()
// ..sort((e1, e2) => e2.value.compareTo(e1.value)),
// );
for (MapEntry<String, double> entry in objectTags.entries) {
chipButtons.add(
ChipButtonWidget(
entry.key +
(kDebugMode
? "-" + (entry.value * 100).round().toString()
: ""),
),
);
}
// for (MapEntry<String, double> entry in objectTags.entries) {
// chipButtons.add(
// ChipButtonWidget(
// entry.key +
// (kDebugMode
// ? "-" + (entry.value * 100).round().toString()
// : ""),
// ),
// );
// }
return chipButtons;
} catch (e, s) {
Logger("ObjctsItemWidget").info(e, s);
return [];
}
}
}
// return chipButtons;
// } catch (e, s) {
// Logger("ObjctsItemWidget").info(e, s);
// return [];
// }
// }
// }

View file

@ -4,7 +4,6 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import "package:path/path.dart";
import 'package:photo_manager/photo_manager.dart';
import 'package:photos/core/constants.dart';
import 'package:photos/core/event_bus.dart';

View file

@ -193,46 +193,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
camera:
dependency: transitive
description:
name: camera
sha256: "3ad71371b8168a4c8012c0b40a53c05afc75d46cc688b0f37b4611a841d47b25"
url: "https://pub.dev"
source: hosted
version: "0.9.8+1"
camera_android:
dependency: transitive
description:
name: camera_android
sha256: "665d62c1f334722c7519ca5d3b94ad68ecaa801691870602da5638a42c1fff67"
url: "https://pub.dev"
source: hosted
version: "0.9.8+3"
camera_avfoundation:
dependency: transitive
description:
name: camera_avfoundation
sha256: "1a416e452b30955b392f4efbf23291d3f2ba3660a85e1628859eb62d2a2bab26"
url: "https://pub.dev"
source: hosted
version: "0.9.13+2"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
sha256: "60fa0bb62a4f3bf3a7c413e31e4cd01b69c779ccc8e4668904a24581b86c316b"
url: "https://pub.dev"
source: hosted
version: "2.5.1"
camera_web:
dependency: transitive
description:
name: camera_web
sha256: "18cdbee5441e9a6fb129fdd9b68a06d1b8c5236932ba97d5faeaefe80db2e5bd"
url: "https://pub.dev"
source: hosted
version: "0.2.1+6"
characters:
dependency: transitive
description:
@ -258,6 +218,14 @@ packages:
url: "https://github.com/ente-io/chewie.git"
source: git
version: "1.7.0"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7
url: "https://pub.dev"
source: hosted
version: "0.4.0"
clock:
dependency: transitive
description:
@ -663,13 +631,13 @@ packages:
source: hosted
version: "5.7.2+3"
flutter_launcher_icons:
dependency: "direct main"
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "559c600f056e7c704bd843723c21e01b5fba47e8824bd02422165bcc02a5de1d"
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
url: "https://pub.dev"
source: hosted
version: "0.9.3"
version: "0.13.1"
flutter_lints:
dependency: "direct dev"
description:
@ -735,10 +703,10 @@ packages:
dependency: "direct main"
description:
name: flutter_native_splash
sha256: "6777a3abb974021a39b5fdd2d46a03ca390e03903b6351f21d10e7ecc969f12d"
sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698
url: "https://pub.dev"
source: hosted
version: "2.2.16"
version: "2.3.2"
flutter_password_strength:
dependency: "direct main"
description:
@ -910,10 +878,10 @@ packages:
dependency: transitive
description:
name: html
sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
url: "https://pub.dev"
source: hosted
version: "0.15.3"
version: "0.15.4"
http:
dependency: "direct main"
description:
@ -950,10 +918,10 @@ packages:
dependency: "direct main"
description:
name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf
url: "https://pub.dev"
source: hosted
version: "3.3.0"
version: "4.0.17"
image_editor:
dependency: "direct main"
description:
@ -1397,10 +1365,10 @@ packages:
dependency: transitive
description:
name: petitparser
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.1.0"
version: "5.4.0"
photo_manager:
dependency: "direct main"
description:
@ -1886,15 +1854,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.9.1"
tflite_flutter_helper:
dependency: "direct main"
description:
path: "."
ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
resolved-ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
url: "https://github.com/elephantum/tflite_flutter_helper.git"
source: git
version: "0.3.0"
timezone:
dependency: transitive
description:
@ -1963,10 +1922,10 @@ packages:
dependency: transitive
description:
name: universal_io
sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d"
sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.2.2"
url_launcher:
dependency: "direct main"
description:
@ -2212,10 +2171,10 @@ packages:
dependency: transitive
description:
name: xml
sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.2.2"
version: "6.3.0"
xmlstream:
dependency: transitive
description:

View file

@ -65,13 +65,12 @@ dependencies:
flutter_email_sender: ^5.2.0
flutter_image_compress: ^1.1.0
flutter_inappwebview: ^5.5.0+2
flutter_launcher_icons: ^0.9.3
flutter_local_notifications: ^12.0.4
flutter_localizations:
sdk: flutter
flutter_map: ^4.0.0
flutter_map_marker_cluster: ^1.1.1
flutter_native_splash: ^2.2.0+1
flutter_native_splash: ^2.3.1
flutter_password_strength: ^0.1.6
flutter_secure_storage: ^8.0.0
flutter_sodium: ^0.2.0
@ -80,7 +79,7 @@ dependencies:
freezed_annotation: ^2.2.0
google_nav_bar: ^5.0.5
http: ^0.13.4
image: ^3.0.2
image: ^4.0.17
image_editor: ^1.3.0
in_app_purchase: ^3.0.7
intl: ^0.18.0
@ -128,10 +127,10 @@ dependencies:
syncfusion_flutter_core: ^19.2.49
syncfusion_flutter_sliders: ^19.2.49
tflite_flutter: ^0.9.0
tflite_flutter_helper:
git:
url: https://github.com/elephantum/tflite_flutter_helper.git # Fixes https://github.com/am15h/tflite_flutter_helper/issues/57
ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
# tflite_flutter_helper:
# git:
# url: https://github.com/elephantum/tflite_flutter_helper.git # Fixes https://github.com/am15h/tflite_flutter_helper/issues/57
# ref: a7d7a59a33f7cffa0a2a12ab05625807622cc97a
tuple: ^2.0.0
uni_links: ^0.5.1
url_launcher: ^6.0.3
@ -168,6 +167,7 @@ dev_dependencies:
build_runner: ^2.3.3
flutter_driver:
sdk: flutter
flutter_launcher_icons: ^0.13.1
flutter_lints: ^2.0.1
flutter_test:
sdk: flutter
@ -177,18 +177,20 @@ dev_dependencies:
json_serializable: ^6.6.1
test: ^1.22.0
flutter_icons:
android: "launcher_icon"
adaptive_icon_foreground: "assets/launcher_icon/ente-icon-foreground.png"
adaptive_icon_background: "#ffffff"
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/icon-light.png"
image_path: "assets/launcher_icon/icon.png"
adaptive_icon_foreground: "assets/launcher_icon/adaptive_icon.png"
adaptive_icon_background: "#ffffff"
remove_alpha_ios: true
min_sdk_android: 21
flutter_native_splash:
color: "#ffffff"
color_dark: "#000000"
image: assets/splash-screen-light.png
image_dark: assets/splash-screen-dark.png
image: assets/splash-icon-light.png
image_dark: assets/splash-icon-dark.png
android_fullscreen: true
android_gravity: center
ios_content_mode: center
@ -198,8 +200,8 @@ flutter_native_splash:
# Please note that the splash screen will be clipped to a circle on the center of the screen.
# App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
# 768 pixels in diameter.
image: assets/splash-screen-light.png
image_dark: assets/splash-screen-dark.png
image: assets/splash-icon-light.png
image_dark: assets/splash-icon-dark.png
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec