From 3841ad93a848212cdbd563c0f388b5ec748b63c4 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Mon, 20 Jan 2020 15:30:03 -0800 Subject: [PATCH] Compute distance for identities Signed-off-by: James Ketrenos --- server/routes/identities.js | 64 +++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/server/routes/identities.js b/server/routes/identities.js index 25c42a7..121ed15 100755 --- a/server/routes/identities.js +++ b/server/routes/identities.js @@ -1,6 +1,7 @@ "use strict"; -const express = require("express"); +const express = require("express"), + Promise = require("bluebird"); let photoDB; @@ -84,9 +85,23 @@ router.post("/", (req, res) => { }); }); +function bufferToFloat32Array(buffer) { + return new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Float32Array.BYTES_PER_ELEMENT); +} + +function euclideanDistance(a, b) { + let A = bufferToFloat32Array(a); + let B = bufferToFloat32Array(b); + let sum = 0; + for (let i = 0; i < 128; i++) { + let delta = A[i] - B[i]; + sum += delta * delta; + } + return Math.sqrt(sum); +} + router.get("/:id?", (req, res) => { let id; - console.log("here"); if (req.params.id) { id = parseInt(req.params.id); @@ -111,7 +126,6 @@ router.get("/:id?", (req, res) => { type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }).then((identities) => { - console.log("asdf"); identities.forEach((identity) => { const relatedFaces = identity.relatedFaceIds.split(","), relatedFacePhotos = identity.relatedFacePhotoIds.split(","); @@ -132,24 +146,40 @@ router.get("/:id?", (req, res) => { console.log("No score request."); return identities; } - console.log("Looking up scores."); + console.log("Looking up score against: " + req.query.withScore); - return photoDB.sequelize.query("SELECT * FROM facedescriptor WHERE faceId IN (:faceIds)", { - replacements: { - faceIds: relatedFaces - }, - type: photoDB.Sequelize.QueryTypes.SELECT, - raw: true - }).then((descriptors) => { - descriptors.forEach((descriptor) => { - for (let i = 0; i < identity.relatedFaces.length; i++) { - if (identity.relatedFaces[i].faceId == descriptor.faceId) { - identity.relatedFaces[i].descriptors = descriptor.descriptors; - return; + return Promise.map(identities, (identity) => { + return photoDB.sequelize.query("SELECT * FROM facedescriptors WHERE faceId IN (:id,:faceIds)", { + replacements: { + id: parseInt(req.query.withScore), + faceIds: identity.relatedFaces.map(face => face.faceId) + }, + type: photoDB.Sequelize.QueryTypes.SELECT, + raw: true + }).then((descriptors) => { + let target; + for (let i = 0; i < descriptors.length; i++) { + if (descriptors[i].faceId == req.query.withScore) { + target = descriptors[i].descriptors; + break; } } - }); + if (!target) { + console.warn("Could not find descriptor for requested face: " + req.query.withScore); + return; + } + descriptors.forEach((descriptor) => { + for (let i = 0; i < identity.relatedFaces.length; i++) { + if (identity.relatedFaces[i].faceId == descriptor.faceId) { + identity.relatedFaces[i].distance = euclideanDistance(target, descriptor.descriptors) + identity.relatedFaces[i].descriptors = descriptor.descriptors; + return; + } + } + }); + }); + }).then(() => { return identities; }); }).then((identities) => {