From 3d952120233fe9de9b5a8a2dfc46422bfb4aba08 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 29 Aug 2024 19:20:56 +0530 Subject: [PATCH] Preview --- web/apps/photos/src/pages/cluster-debug.tsx | 61 +++++++++++-------- .../new/photos/services/ml/cluster-new.ts | 7 ++- web/packages/new/photos/services/ml/index.ts | 5 +- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/web/apps/photos/src/pages/cluster-debug.tsx b/web/apps/photos/src/pages/cluster-debug.tsx index dcffaecfd2..23930f1f03 100644 --- a/web/apps/photos/src/pages/cluster-debug.tsx +++ b/web/apps/photos/src/pages/cluster-debug.tsx @@ -4,10 +4,9 @@ import { faceCrop, wipClusterDebugPageContents, type ClusterDebugPageContents, - type FaceFileNeighbour, - type FaceFileNeighbours, + type ClusterPreviewFaceWF, + type ClusterPreviewWF, } from "@/new/photos/services/ml"; -import type { Face } from "@/new/photos/services/ml/face"; import { FlexWrapper, FluidContainer, @@ -15,7 +14,7 @@ import { } from "@ente/shared/components/Container"; import EnteSpinner from "@ente/shared/components/EnteSpinner"; import BackButton from "@mui/icons-material/ArrowBackOutlined"; -import { Box, IconButton, styled, Typography } from "@mui/material"; +import { Box, IconButton, Stack, styled, Typography } from "@mui/material"; import { useRouter } from "next/router"; import { AppContext } from "pages/_app"; import React, { useContext, useEffect, useMemo, useRef, useState } from "react"; @@ -53,8 +52,9 @@ export default function ClusterDebug() { {`${clusterRes.clusters.length} clusters`} - Showing only top 20 and bottom 10 clusters (and only up to 50 faces in - each, sorted by cosine distance to highest scoring face in the cluster). + Showing only top 20 and bottom 10 clusters (and only up to 50 + faces in each, sorted by cosine distance to highest scoring face + in the cluster).
@@ -112,7 +112,7 @@ const ClusterPhotoList: React.FC = ({ width, clusterRes, }) => { - const { faceFNs, clusterIDForFaceID } = clusterRes; + const { clusterPreviewWFs, clusterIDForFaceID } = clusterRes; const [itemList, setItemList] = useState([]); const listRef = useRef(null); @@ -125,8 +125,8 @@ const ClusterPhotoList: React.FC = ({ const listItemHeight = 120 * shrinkRatio + 24 + 4; useEffect(() => { - setItemList(itemListFromFaceFNs(faceFNs, columns)); - }, [columns, faceFNs]); + setItemList(itemListFromClusterPreviewWFs(clusterPreviewWFs, columns)); + }, [columns, clusterPreviewWFs]); useEffect(() => { listRef.current?.resetAfterIndex(0); @@ -138,7 +138,7 @@ const ClusterPhotoList: React.FC = ({ const generateKey = (i: number) => Array.isArray(itemList[i]) ? `${itemList[i][0].enteFile.id}/${itemList[i][0].face.faceID}-${itemList[i].slice(-1)[0].enteFile.id}/${itemList[i].slice(-1)[0].face.faceID}-${i}` - : `${itemList[i].faceID}-${i}`; + : `${itemList[i]}-${i}`; return ( = ({ > {!Array.isArray(item) ? ( - {`score ${item.score.toFixed(2)} blur ${item.blur.toFixed(0)}`} + {`cluster size ${item.toFixed(2)}`} ) : ( - item.map((faceFN, i) => ( + item.map((faceWF, i) => ( )) )} @@ -181,19 +181,20 @@ const ClusterPhotoList: React.FC = ({ ); }; -type ItemListItem = Face | FaceFileNeighbour[]; +// type ItemListItem = Face | FaceFileNeighbour[]; +type ItemListItem = number | ClusterPreviewFaceWF[]; -const itemListFromFaceFNs = ( - faceFNs: FaceFileNeighbours[], +const itemListFromClusterPreviewWFs = ( + clusterPreviewWFs: ClusterPreviewWF[], columns: number, ) => { const result: ItemListItem[] = []; - for (let index = 0; index < faceFNs.length; index++) { - const { face, neighbours } = faceFNs[index]; - result.push(face); + for (let index = 0; index < clusterPreviewWFs.length; index++) { + const { clusterSize, faces } = clusterPreviewWFs[index]; + result.push(clusterSize); let lastIndex = 0; - while (lastIndex < neighbours.length) { - result.push(neighbours.slice(lastIndex, lastIndex + columns)); + while (lastIndex < faces.length) { + result.push(faces.slice(lastIndex, lastIndex + columns)); lastIndex += columns; } } @@ -210,12 +211,12 @@ const getShrinkRatio = (width: number, columns: number) => (columns * 120); interface FaceItemProps { - faceFN: FaceFileNeighbour; + faceWF: ClusterPreviewFaceWF; clusterIDForFaceID: Map; } -const FaceItem: React.FC = ({ faceFN, clusterIDForFaceID }) => { - const { face, enteFile, cosineSimilarity } = faceFN; +const FaceItem: React.FC = ({ faceWF, clusterIDForFaceID }) => { + const { face, enteFile, cosineSimilarity } = faceWF; const { faceID } = face; const [objectURL, setObjectURL] = useState(); @@ -252,9 +253,15 @@ const FaceItem: React.FC = ({ faceFN, clusterIDForFaceID }) => { src={objectURL} /> )} - - {cosineSimilarity.toFixed(2)} - + + + {`${face.blur.toFixed(0)} blr`} + + + + {`cos ${cosineSimilarity.toFixed(2)}`} + + ); }; diff --git a/web/packages/new/photos/services/ml/cluster-new.ts b/web/packages/new/photos/services/ml/cluster-new.ts index 983c128a6a..e2bf78eb35 100644 --- a/web/packages/new/photos/services/ml/cluster-new.ts +++ b/web/packages/new/photos/services/ml/cluster-new.ts @@ -352,7 +352,10 @@ export const clusterFacesHdb = async (faceIndexes: FaceIndex[]) => { const t = Date.now(); // A flattened array of faces. - const faces0 = [...enumerateFaces(faceIndexes)]; + // TODO-Cluster ad-hoc filtering and slicing + const faces0 = [...enumerateFaces(faceIndexes)] + .filter((f) => f.blur > 50) + .slice(0, 1000); // TODO-Cluster testing code, can be removed once done const faces = Array(1) .fill(0) @@ -433,7 +436,7 @@ export const clusterFacesHdb = async (faceIndexes: FaceIndex[]) => { // Use a higher cosine similarity threshold if either of the two // faces are blurry. const threshold = - existingFace.blur < 100 || newFace.blur < 100 ? 0.84 : 0.7; + existingFace.blur < 100 || newFace.blur < 100 ? 0.9 : 0.7; if (csim > threshold && csim > nnCosineSimilarity) { nnCluster = existingCluster; nnCosineSimilarity = csim; diff --git a/web/packages/new/photos/services/ml/index.ts b/web/packages/new/photos/services/ml/index.ts index df8d08235c..699a9b9c14 100644 --- a/web/packages/new/photos/services/ml/index.ts +++ b/web/packages/new/photos/services/ml/index.ts @@ -366,14 +366,15 @@ export interface ClusterPreviewWF { faces: ClusterPreviewFaceWF[]; } -interface ClusterPreviewFaceWF { +export interface ClusterPreviewFaceWF { face: Face; enteFile: EnteFile; cosineSimilarity: number; } export interface ClusterDebugPageContents { - faceFNs: FaceFileNeighbours[]; + // faceFNs: FaceFileNeighbours[]; + clusterPreviewWFs: ClusterPreviewWF[]; clusters: FaceCluster[]; clusterIDForFaceID: Map; }