diff --git a/src/components/MlDebug.tsx b/src/components/MlDebug.tsx index e33a197c5..19d5d1361 100644 --- a/src/components/MlDebug.tsx +++ b/src/components/MlDebug.tsx @@ -15,7 +15,7 @@ export default function MLDebug() { const [minClusterSize, setMinClusterSize] = useState(4); const [minFaceSize, setMinFaceSize] = useState(24); const [batchSize, setBatchSize] = useState(50); - const [maxFaceDistance, setMaxFaceDistance] = useState(0.55); + const [maxFaceDistance, setMaxFaceDistance] = useState(0.5); const [mlResult, setMlResult] = useState({ allFaces: [], clustersWithNoise: { diff --git a/src/services/machineLearning/machineLearningService.ts b/src/services/machineLearning/machineLearningService.ts index fea3fb406..08cfc7c03 100644 --- a/src/services/machineLearning/machineLearningService.ts +++ b/src/services/machineLearning/machineLearningService.ts @@ -25,6 +25,7 @@ import ClusteringService from './clusteringService'; import './faceEnvPatch'; import * as faceapi from 'face-api.js'; import { euclideanDistance, SsdMobilenetv1Options } from 'face-api.js'; +import { f32Average } from 'utils/machineLearning'; class MachineLearningService { // private faceDetectionService: TFJSFaceDetectionService; @@ -32,7 +33,7 @@ class MachineLearningService { private clusteringService: ClusteringService; private clusterFaceDistance = 0.4; - private maxFaceDistance = 0.55; + private maxFaceDistance = 0.5; private minClusterSize = 4; private minFaceSize = 24; private batchSize = 50; @@ -87,11 +88,17 @@ class MachineLearningService { } private getClusterSummary(cluster: ClusterFaces): FaceDescriptor { - const faceScore = (f) => f.detection.score; // f.alignedRect.box.width * + // const faceScore = (f) => f.detection.score; // f.alignedRect.box.width * - return cluster - .map((f) => this.allFaces[f].face) - .sort((f1, f2) => faceScore(f2) - faceScore(f1))[0].descriptor; + // return cluster + // .map((f) => this.allFaces[f].face) + // .sort((f1, f2) => faceScore(f2) - faceScore(f1))[0].descriptor; + + const descriptors = cluster.map( + (f) => this.allFaces[f].face.descriptor + ); + + return f32Average(descriptors); } private updateClusterSummaries() { @@ -271,7 +278,7 @@ class MachineLearningService { .detectAllFaces( tfImage as any, new SsdMobilenetv1Options({ - // minConfidence: 0.6 + minConfidence: 0.75, // maxResults: 10 }) ) diff --git a/src/utils/machineLearning/index.ts b/src/utils/machineLearning/index.ts new file mode 100644 index 000000000..8a2a83479 --- /dev/null +++ b/src/utils/machineLearning/index.ts @@ -0,0 +1,22 @@ +export function f32Average(descriptors: Float32Array[]) { + if (descriptors.length < 1) { + throw Error('f32Average: input size 0'); + } + + if (descriptors.length === 1) { + return descriptors[0]; + } + + const f32Size = descriptors[0].length; + const avg = new Float32Array(f32Size); + + for (let index = 0; index < f32Size; index++) { + avg[index] = descriptors[0][index]; + for (let desc = 1; desc < descriptors.length; desc++) { + avg[index] = avg[index] + descriptors[desc][index]; + } + avg[index] = avg[index] / descriptors.length; + } + + return avg; +}