Manav Rathi 1 年之前
父节点
当前提交
77bacc518c

+ 58 - 4
web/apps/photos/src/services/machineLearning/faceService.ts

@@ -5,15 +5,14 @@ import {
     Face,
     MLSyncContext,
     MLSyncFileContext,
+    type FaceAlignment,
+    type Versioned,
 } from "services/ml/types";
-import { imageBitmapToBlob } from "utils/image";
+import { imageBitmapToBlob, warpAffineFloat32List } from "utils/image";
 import {
-    areFaceIdsSame,
-    extractFaceImagesToFloat32,
     getFaceId,
     getLocalFile,
     getOriginalImageBitmap,
-    isDifferentOrOld,
 } from "utils/machineLearning";
 import mlIDbStorage from "utils/storage/mlIDbStorage";
 import ReaderService from "./readerService";
@@ -304,3 +303,58 @@ class FaceService {
 }
 
 export default new FaceService();
+
+export function areFaceIdsSame(ofFaces: Array<Face>, toFaces: Array<Face>) {
+    if (
+        (ofFaces === null || ofFaces === undefined) &&
+        (toFaces === null || toFaces === undefined)
+    ) {
+        return true;
+    }
+    return primitiveArrayEquals(
+        ofFaces?.map((f) => f.id),
+        toFaces?.map((f) => f.id),
+    );
+}
+
+function primitiveArrayEquals(a, b) {
+    return (
+        Array.isArray(a) &&
+        Array.isArray(b) &&
+        a.length === b.length &&
+        a.every((val, index) => val === b[index])
+    );
+}
+
+export function isDifferentOrOld(
+    method: Versioned<string>,
+    thanMethod: Versioned<string>,
+) {
+    return (
+        !method ||
+        method.value !== thanMethod.value ||
+        method.version < thanMethod.version
+    );
+}
+
+async function extractFaceImagesToFloat32(
+    faceAlignments: Array<FaceAlignment>,
+    faceSize: number,
+    image: ImageBitmap,
+): Promise<Float32Array> {
+    const faceData = new Float32Array(
+        faceAlignments.length * faceSize * faceSize * 3,
+    );
+    for (let i = 0; i < faceAlignments.length; i++) {
+        const alignedFace = faceAlignments[i];
+        const faceDataOffset = i * faceSize * faceSize * 3;
+        warpAffineFloat32List(
+            image,
+            alignedFace,
+            faceSize,
+            faceData,
+            faceDataOffset,
+        );
+    }
+    return faceData;
+}

+ 27 - 8
web/apps/photos/src/services/machineLearning/peopleService.ts

@@ -1,14 +1,8 @@
 import log from "@/next/log";
 import { Face, MLSyncContext, Person } from "services/ml/types";
-import {
-    findFirstIfSorted,
-    getAllFacesFromMap,
-    getLocalFile,
-    getOriginalImageBitmap,
-    isDifferentOrOld,
-} from "utils/machineLearning";
+import { getLocalFile, getOriginalImageBitmap } from "utils/machineLearning";
 import mlIDbStorage from "utils/storage/mlIDbStorage";
-import FaceService from "./faceService";
+import FaceService, { isDifferentOrOld } from "./faceService";
 
 class PeopleService {
     async syncPeopleIndex(syncContext: MLSyncContext) {
@@ -92,3 +86,28 @@ class PeopleService {
 }
 
 export default new PeopleService();
+
+function findFirstIfSorted<T>(
+    elements: Array<T>,
+    comparator: (a: T, b: T) => number,
+) {
+    if (!elements || elements.length < 1) {
+        return;
+    }
+    let first = elements[0];
+
+    for (let i = 1; i < elements.length; i++) {
+        const comp = comparator(elements[i], first);
+        if (comp < 0) {
+            first = elements[i];
+        }
+    }
+
+    return first;
+}
+
+function getAllFacesFromMap(allFacesMap: Map<number, Array<Face>>) {
+    const allFaces = [...allFacesMap.values()].flat();
+
+    return allFaces;
+}

+ 0 - 0
web/apps/photos/src/utils/machineLearning/faceAlign.ts


+ 0 - 81
web/apps/photos/src/utils/machineLearning/index.ts

@@ -11,46 +11,18 @@ import {
     FaceAlignment,
     MlFileData,
     Person,
-    Versioned,
 } from "services/ml/types";
 import { EnteFile } from "types/file";
 import { getRenderableImage } from "utils/file";
 import { clamp, warpAffineFloat32List } from "utils/image";
 import mlIDbStorage from "utils/storage/mlIDbStorage";
 
-export function getAllFacesFromMap(allFacesMap: Map<number, Array<Face>>) {
-    const allFaces = [...allFacesMap.values()].flat();
-
-    return allFaces;
-}
 
 export async function getLocalFile(fileId: number) {
     const localFiles = await getLocalFiles();
     return localFiles.find((f) => f.id === fileId);
 }
 
-export async function extractFaceImagesToFloat32(
-    faceAlignments: Array<FaceAlignment>,
-    faceSize: number,
-    image: ImageBitmap,
-): Promise<Float32Array> {
-    const faceData = new Float32Array(
-        faceAlignments.length * faceSize * faceSize * 3,
-    );
-    for (let i = 0; i < faceAlignments.length; i++) {
-        const alignedFace = faceAlignments[i];
-        const faceDataOffset = i * faceSize * faceSize * 3;
-        warpAffineFloat32List(
-            image,
-            alignedFace,
-            faceSize,
-            faceData,
-            faceDataOffset,
-        );
-    }
-    return faceData;
-}
-
 export function getFaceId(detectedFace: DetectedFace, imageDims: Dimensions) {
     const xMin = clamp(
         detectedFace.detection.box.x / imageDims.width,
@@ -192,56 +164,3 @@ export async function getAllPeople(limit: number = undefined) {
         .sort((p1, p2) => p2.files.length - p1.files.length)
         .slice(0, limit);
 }
-
-export function findFirstIfSorted<T>(
-    elements: Array<T>,
-    comparator: (a: T, b: T) => number,
-) {
-    if (!elements || elements.length < 1) {
-        return;
-    }
-    let first = elements[0];
-
-    for (let i = 1; i < elements.length; i++) {
-        const comp = comparator(elements[i], first);
-        if (comp < 0) {
-            first = elements[i];
-        }
-    }
-
-    return first;
-}
-
-export function isDifferentOrOld(
-    method: Versioned<string>,
-    thanMethod: Versioned<string>,
-) {
-    return (
-        !method ||
-        method.value !== thanMethod.value ||
-        method.version < thanMethod.version
-    );
-}
-
-function primitiveArrayEquals(a, b) {
-    return (
-        Array.isArray(a) &&
-        Array.isArray(b) &&
-        a.length === b.length &&
-        a.every((val, index) => val === b[index])
-    );
-}
-
-export function areFaceIdsSame(ofFaces: Array<Face>, toFaces: Array<Face>) {
-    if (
-        (ofFaces === null || ofFaces === undefined) &&
-        (toFaces === null || toFaces === undefined)
-    ) {
-        return true;
-    }
-    return primitiveArrayEquals(
-        ofFaces?.map((f) => f.id),
-        toFaces?.map((f) => f.id),
-    );
-}
-