diff --git a/mobile/lib/face/db.dart b/mobile/lib/face/db.dart index e9e6079204..9b5f42f540 100644 --- a/mobile/lib/face/db.dart +++ b/mobile/lib/face/db.dart @@ -688,6 +688,20 @@ class FaceMLDataDB { return clusteredFiles / indexableFiles; } + Future getUnclusteredFaceCount() async { + final db = await instance.asyncDB; + const String query = ''' + SELECT f.$faceIDColumn + FROM $facesTable f + LEFT JOIN $faceClustersTable fc ON f.$faceIDColumn = fc.$fcFaceId + WHERE f.$faceScore > $kMinimumQualityFaceScore + AND f.$faceBlur > $kLaplacianHardThreshold + AND fc.$fcFaceId IS NULL + '''; + final List> maps = await db.getAll(query); + return maps.length; + } + Future getBlurryFaceCount([ int blurThreshold = kLaplacianHardThreshold, ]) async { 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 932c7e39e1..a6b38f8e3b 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 @@ -98,6 +98,7 @@ class FaceMlService { final int _fileDownloadLimit = 5; final int _embeddingFetchLimit = 200; + final int _kForceClusteringFaceCount = 4000; Future init({bool initializeImageMlIsolate = false}) async { if (LocalSettings.instance.isFaceIndexingEnabled == false) { @@ -357,6 +358,15 @@ class FaceMlService { if (_cannotRunMLFunction()) return; await sync(forceSync: _shouldSyncPeople); + + final int unclusteredFacesCount = + await FaceMLDataDB.instance.getUnclusteredFaceCount(); + if (unclusteredFacesCount > _kForceClusteringFaceCount) { + _logger.info( + "There are $unclusteredFacesCount unclustered faces, doing clustering first", + ); + await clusterAllImages(); + } await indexAllImages(); await clusterAllImages(); }