mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 07:28:26 +00:00
Clusterface (#4626)
## Description Fixed bug where we showed "Face not clustered yet, please come back later" toast message even for faces which had a score too low to ever be clustered automatically.
This commit is contained in:
commit
50c65125a7
@ -604,8 +604,6 @@ class MLDataDB {
|
||||
}
|
||||
|
||||
Future<List<FaceDbInfoForClustering>> getFaceInfoForClustering({
|
||||
double minScore = kMinimumQualityFaceScore,
|
||||
int minClarity = kLaplacianHardThreshold,
|
||||
int maxFaces = 20000,
|
||||
int offset = 0,
|
||||
int batchSize = 10000,
|
||||
@ -622,7 +620,7 @@ class MLDataDB {
|
||||
// Query a batch of rows
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
'SELECT $faceIDColumn, $embeddingColumn, $faceScore, $faceBlur, $isSideways FROM $facesTable'
|
||||
' WHERE $faceScore > $minScore AND $faceBlur > $minClarity'
|
||||
' WHERE $faceScore > $kMinimumQualityFaceScore AND $faceBlur > $kLaplacianHardThreshold'
|
||||
' ORDER BY $faceIDColumn'
|
||||
' DESC LIMIT $batchSize OFFSET $offset',
|
||||
);
|
||||
@ -698,12 +696,10 @@ class MLDataDB {
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<int> getTotalFaceCount({
|
||||
double minFaceScore = kMinimumQualityFaceScore,
|
||||
}) async {
|
||||
Future<int> getTotalFaceCount() async {
|
||||
final db = await instance.asyncDB;
|
||||
final List<Map<String, dynamic>> maps = await db.getAll(
|
||||
'SELECT COUNT(*) as count FROM $facesTable WHERE $faceScore > $minFaceScore AND $faceBlur > $kLaplacianHardThreshold',
|
||||
'SELECT COUNT(*) as count FROM $facesTable WHERE $faceScore > $kMinimumQualityFaceScore AND $faceBlur > $kLaplacianHardThreshold',
|
||||
);
|
||||
return maps.first['count'] as int;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import "package:photos/services/filedata/filedata_service.dart";
|
||||
import "package:photos/services/filedata/model/file_data.dart";
|
||||
import 'package:photos/services/machine_learning/face_ml/face_clustering/face_clustering_service.dart';
|
||||
import "package:photos/services/machine_learning/face_ml/face_clustering/face_db_info_for_clustering.dart";
|
||||
import 'package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart';
|
||||
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
|
||||
import "package:photos/services/machine_learning/ml_indexing_isolate.dart";
|
||||
import 'package:photos/services/machine_learning/ml_result.dart';
|
||||
@ -238,10 +237,7 @@ class MLService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clusterAllImages({
|
||||
double minFaceScore = kMinimumQualityFaceScore,
|
||||
bool clusterInBuckets = true,
|
||||
}) async {
|
||||
Future<void> clusterAllImages({bool clusterInBuckets = true}) async {
|
||||
if (_cannotRunMLFunction()) return;
|
||||
|
||||
_logger.info("`clusterAllImages()` called");
|
||||
@ -269,13 +265,12 @@ class MLService {
|
||||
|
||||
// Get a sense of the total number of faces in the database
|
||||
final int totalFaces =
|
||||
await MLDataDB.instance.getTotalFaceCount(minFaceScore: minFaceScore);
|
||||
await MLDataDB.instance.getTotalFaceCount();
|
||||
final fileIDToCreationTime =
|
||||
await FilesDB.instance.getFileIDToCreationTime();
|
||||
final startEmbeddingFetch = DateTime.now();
|
||||
// read all embeddings
|
||||
final result = await MLDataDB.instance.getFaceInfoForClustering(
|
||||
minScore: minFaceScore,
|
||||
maxFaces: totalFaces,
|
||||
);
|
||||
final Set<int> missingFileIDs = {};
|
||||
|
@ -5,12 +5,13 @@ import "package:flutter/cupertino.dart";
|
||||
import "package:flutter/foundation.dart" show kDebugMode;
|
||||
import "package:flutter/material.dart";
|
||||
import "package:photos/db/ml/db.dart";
|
||||
import "package:photos/extensions/stop_watch.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/models/base/id.dart";
|
||||
import 'package:photos/models/file/file.dart';
|
||||
import "package:photos/models/ml/face/face.dart";
|
||||
import "package:photos/models/ml/face/person.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/face_detection/detection.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart";
|
||||
import "package:photos/services/search_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
@ -68,16 +69,13 @@ class _FaceWidgetState extends State<FaceWidget> {
|
||||
if (widget.editMode) return;
|
||||
|
||||
log(
|
||||
"FaceWidget is tapped, with person ${widget.person} and clusterID ${widget.clusterID}",
|
||||
"FaceWidget is tapped, with person ${widget.person?.data.name} and clusterID ${widget.clusterID}",
|
||||
name: "FaceWidget",
|
||||
);
|
||||
if (widget.person == null && widget.clusterID == null) {
|
||||
// Get faceID and double check that it doesn't belong to an existing clusterID. If it does, push that cluster page
|
||||
final w = (kDebugMode ? EnteWatch('FaceWidget') : null)
|
||||
?..start();
|
||||
// Double check that it doesn't belong to an existing clusterID.
|
||||
final existingClusterID = await MLDataDB.instance
|
||||
.getClusterIDForFaceID(widget.face.faceID);
|
||||
w?.log('getting existing clusterID for faceID');
|
||||
if (existingClusterID != null) {
|
||||
final fileIdsToClusterIds =
|
||||
await MLDataDB.instance.getFileIdToClusterIds();
|
||||
@ -99,6 +97,24 @@ class _FaceWidgetState extends State<FaceWidget> {
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (widget.face.score <= kMinimumQualityFaceScore) {
|
||||
// The face score is too low for automatic clustering,
|
||||
// assigning a manual new clusterID so that the user can cluster it manually
|
||||
final String clusterID = newClusterID();
|
||||
await MLDataDB.instance.updateFaceIdToClusterId(
|
||||
{widget.face.faceID: clusterID},
|
||||
);
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ClusterPage(
|
||||
[widget.file],
|
||||
clusterID: clusterID,
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
showShortToast(
|
||||
|
Loading…
x
Reference in New Issue
Block a user