From b956cbdb53e13ba7c1ee7594621d773f20fb5343 Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Mon, 7 Aug 2023 21:11:36 -0300 Subject: [PATCH 1/5] Implement Face Recognition getClustersInternal filtered with fileid --- .../FaceRecognitionBackend.php | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/ClustersBackend/FaceRecognitionBackend.php b/lib/ClustersBackend/FaceRecognitionBackend.php index cbf66914..8d15b5d9 100644 --- a/lib/ClustersBackend/FaceRecognitionBackend.php +++ b/lib/ClustersBackend/FaceRecognitionBackend.php @@ -125,13 +125,9 @@ class FaceRecognitionBackend extends Backend public function getClustersInternal(int $fileid = 0): array { - if ($fileid) { - throw new \Exception('FaceRecognitionBackend: fileid filter not implemented'); - } - $faces = array_merge( - $this->getFaceRecognitionPersons(), - $this->getFaceRecognitionClusters() + $this->getFaceRecognitionPersons($fileid), + $this->getFaceRecognitionClusters($fileid) ); // Post process @@ -225,7 +221,7 @@ class FaceRecognitionBackend extends Backend return (int) $this->config->getAppValue('facerecognition', 'model', -1); } - private function getFaceRecognitionClusters(bool $show_singles = false, bool $show_hidden = false) + private function getFaceRecognitionClusters(int $fileid = 0, bool $show_singles = false, bool $show_hidden = false) { $query = $this->tq->getBuilder(); @@ -255,13 +251,18 @@ class FaceRecognitionBackend extends Backend $query->addGroupBy('frp.user'); $query->where($query->expr()->isNull('frp.name')); + // WHERE these clusters contain fileid if specified + if ($fileid > 0) { + $query->andWhere($query->expr()->eq('fri.file', $query->createNamedParameter($fileid))); + } + // By default hides individual faces when they have no name. - if (!$show_singles) { + if (!$show_singles && !$fileid) { $query->having($query->expr()->gt($count, $query->expr()->literal(1, \PDO::PARAM_INT))); } // By default it shows the people who were not hidden - if (!$show_hidden) { + if (!$show_hidden && !$fileid) { $query->andWhere($query->expr()->eq('frp.is_visible', $query->expr()->literal(1))); } @@ -276,7 +277,7 @@ class FaceRecognitionBackend extends Backend return $this->tq->executeQueryWithCTEs($query)->fetchAll() ?: []; } - private function getFaceRecognitionPersons() + private function getFaceRecognitionPersons(int $fileid = 0) { $query = $this->tq->getBuilder(); @@ -303,6 +304,12 @@ class FaceRecognitionBackend extends Backend // GROUP by name of face clusters $query->where($query->expr()->isNotNull('frp.name')); + + // WHERE these clusters contain fileid if specified + if ($fileid > 0) { + $query->andWhere($query->expr()->eq('fri.file', $query->createNamedParameter($fileid))); + } + $query->groupBy('frp.user'); $query->addGroupBy('frp.name'); From 4e98eddb530228ee4c464726b6fb4246acb17a66 Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Mon, 7 Aug 2023 21:15:57 -0300 Subject: [PATCH 2/5] Metadata: Uses FaceRecognition clusters when the route if from this application. --- src/components/Metadata.vue | 6 +++++- src/mixins/GlobalMixin.ts | 3 +++ src/types.ts | 1 + src/vue-globals.d.ts | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/Metadata.vue b/src/components/Metadata.vue index 69443953..83c0060c 100644 --- a/src/components/Metadata.vue +++ b/src/components/Metadata.vue @@ -352,7 +352,10 @@ export default defineComponent({ }, people(): IFace[] { - return this.baseInfo?.clusters?.recognize ?? []; + if (this.routeIsFaceRecognition) + return this.baseInfo?.clusters?.facerecognition ?? []; + else + return this.baseInfo?.clusters?.recognize ?? []; }, }, @@ -367,6 +370,7 @@ export default defineComponent({ const clusters = [ this.config.albums_enabled ? 'albums' : null, this.config.recognize_enabled ? 'recognize' : null, + this.config.facerecognition_enabled ? 'facerecognition' : null, ] .filter((c) => c) .join(','); diff --git a/src/mixins/GlobalMixin.ts b/src/mixins/GlobalMixin.ts index fe5a8194..30c4bb42 100644 --- a/src/mixins/GlobalMixin.ts +++ b/src/mixins/GlobalMixin.ts @@ -31,6 +31,9 @@ export default defineComponent({ routeIsRecognizeUnassigned(): boolean { return this.routeIsRecognize && this.$route.params.name === constants.FACE_NULL; }, + routeIsFaceRecognition(): boolean { + return this.$route.name === 'facerecognition'; + }, routeIsArchive(): boolean { return this.$route.name === 'archive'; }, diff --git a/src/types.ts b/src/types.ts index 432f453a..1ac9f1a1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -109,6 +109,7 @@ export interface IImageInfo { clusters?: { albums?: IAlbum[]; recognize?: IFace[]; + facerecognition?: IFace[]; }; } diff --git a/src/vue-globals.d.ts b/src/vue-globals.d.ts index b7d623cf..164fe487 100644 --- a/src/vue-globals.d.ts +++ b/src/vue-globals.d.ts @@ -17,6 +17,7 @@ declare module 'vue' { routeIsPeople: boolean; routeIsRecognize: boolean; routeIsRecognizeUnassigned: boolean; + routeIsFaceRecognition: boolean; routeIsArchive: boolean; routeIsPlaces: boolean; routeIsMap: boolean; From 68e8204ee6fb339af2f9c50072dfc26bb7f6997d Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Tue, 8 Aug 2023 19:21:18 -0300 Subject: [PATCH 3/5] Two small micro optimizations Confidence is not used since the faces scoring method is shared with recognize and fix removal of two parameters in image list response. --- lib/ClustersBackend/FaceRecognitionBackend.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/ClustersBackend/FaceRecognitionBackend.php b/lib/ClustersBackend/FaceRecognitionBackend.php index 8d15b5d9..f490d5a7 100644 --- a/lib/ClustersBackend/FaceRecognitionBackend.php +++ b/lib/ClustersBackend/FaceRecognitionBackend.php @@ -120,7 +120,7 @@ class FaceRecognitionBackend extends Backend 'y' => (float) $row['face_y'] / $row['image_height'], ]; - unset($row['face_x'], $row['face_y'], $row['face_w'], $row['face_h'], $row['image_height'], $row['image_width']); + unset($row['face_x'], $row['face_y'], $row['face_width'], $row['face_height'], $row['image_height'], $row['image_width']); } public function getClustersInternal(int $fileid = 0): array @@ -157,7 +157,6 @@ class FaceRecognitionBackend extends Backend 'frf.height', 'm.w as image_width', // Scoring 'm.h as image_height', - 'frf.confidence', 'm.fileid', 'm.datetaken', // Just in case, for postgres )->from('facerecog_faces', 'frf'); From df918a04de2b1c3b8953f001f68215dace4c13fd Mon Sep 17 00:00:00 2001 From: Matias De lellis Date: Tue, 8 Aug 2023 20:38:15 -0300 Subject: [PATCH 4/5] Don't show the individual clusters but now accordingly with the new version of Face Recogntion. --- .../FaceRecognitionBackend.php | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/ClustersBackend/FaceRecognitionBackend.php b/lib/ClustersBackend/FaceRecognitionBackend.php index f490d5a7..cafaf18d 100644 --- a/lib/ClustersBackend/FaceRecognitionBackend.php +++ b/lib/ClustersBackend/FaceRecognitionBackend.php @@ -220,7 +220,12 @@ class FaceRecognitionBackend extends Backend return (int) $this->config->getAppValue('facerecognition', 'model', -1); } - private function getFaceRecognitionClusters(int $fileid = 0, bool $show_singles = false, bool $show_hidden = false) + private function minFaceInClusters(): int + { + return (int) $this->config->getAppValue('facerecognition', 'min_faces_in_cluster', 5); + } + + private function getFaceRecognitionClusters(int $fileid = 0) { $query = $this->tq->getBuilder(); @@ -250,18 +255,14 @@ class FaceRecognitionBackend extends Backend $query->addGroupBy('frp.user'); $query->where($query->expr()->isNull('frp.name')); - // WHERE these clusters contain fileid if specified + // The query change if we want the people in an fileid, or the unnamed clusters if ($fileid > 0) { + // WHERE these clusters contain fileid if specified $query->andWhere($query->expr()->eq('fri.file', $query->createNamedParameter($fileid))); - } - - // By default hides individual faces when they have no name. - if (!$show_singles && !$fileid) { - $query->having($query->expr()->gt($count, $query->expr()->literal(1, \PDO::PARAM_INT))); - } - - // By default it shows the people who were not hidden - if (!$show_hidden && !$fileid) { + } else { + // WHERE these clusters has a minimum number of faces + $query->having($query->expr()->gte($count, $query->expr()->literal($this->minFaceInClusters(), \PDO::PARAM_INT))); + // WHERE these clusters were not hidden due inconsistencies $query->andWhere($query->expr()->eq('frp.is_visible', $query->expr()->literal(1))); } From 520d0c6b1389a5c1170325aaab851dbdb9bde026 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Wed, 16 Aug 2023 08:40:15 -0700 Subject: [PATCH 5/5] metadata: use face recognition if recognize not available --- src/components/Metadata.vue | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/Metadata.vue b/src/components/Metadata.vue index 83c0060c..21a0d19e 100644 --- a/src/components/Metadata.vue +++ b/src/components/Metadata.vue @@ -352,10 +352,14 @@ export default defineComponent({ }, people(): IFace[] { - if (this.routeIsFaceRecognition) - return this.baseInfo?.clusters?.facerecognition ?? []; - else - return this.baseInfo?.clusters?.recognize ?? []; + const clusters = this.baseInfo?.clusters; + + // force face-recognition on its own route, or if recognize is disabled + if (this.routeIsFaceRecognition || !this.config.recognize_enabled) { + return clusters?.facerecognition ?? []; + } + + return clusters?.recognize ?? []; }, },