"use strict"; const Promise = require("bluebird"); let photoDB; function bufferToFloat32Array(buffer) { return new Float64Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Float64Array.BYTES_PER_ELEMENT); } function euclideanDistance(a, b) { let A = bufferToFloat32Array(a); let B = bufferToFloat32Array(b); console.log(A.length, B.length); let sum = 0; for (let i = 0; i < A.length; i++) { let delta = A[i] - B[i]; sum += delta * delta; } return Math.sqrt(sum); } require("./db/photos").then(function(db) { photoDB = db; }) .then(async () => { const id = 7; const filter = ` WHERE identities.id=:id `; const identities = await photoDB.sequelize.query("SELECT " + "identities.*," + "GROUP_CONCAT(faces.id) AS relatedFaceIds," + "GROUP_CONCAT(faces.descriptorId) AS relatedFaceDescriptorIds," + "GROUP_CONCAT(faces.photoId) AS relatedFacePhotoIds " + "FROM identities " + "INNER JOIN faces ON identities.id=faces.identityId " + filter + "GROUP BY identities.id", { replacements: { id }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }); await Promise.map(identities, async (identity) => { [ 'firstName', 'middleName', 'lastName' ].forEach(key => { if (!identity[key]) { identity[key] = ''; } }); const relatedFaces = identity.relatedFaceIds.split(","), relatedFacePhotos = identity.relatedFacePhotoIds.split(","); let descriptors = await photoDB.sequelize.query( `SELECT descriptors FROM facedescriptors WHERE id in (:ids)`, { replacements: { ids: identity.relatedFaceDescriptorIds.split(',') }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true } ); descriptors = descriptors.map(entry => entry.descriptors); identity.relatedFaces = relatedFaces.map((faceId, index) => { const distance = euclideanDistance( descriptors[index], identity.descriptors ); console.log(index, distance); return { faceId, photoId: relatedFacePhotos[index], distance }; }); identity .relatedFaces .sort((A, B) => { return A.distance - B.distance; }); /* If no filter was specified, only return the best face for * the identity */ if (!filter) { identity.relatedFaces = [ identity.relatedFaces[0] ]; } delete identity.descriptors; delete identity.relatedFaceIds; delete identity.relatedFacePhotoIds; delete identity.relatedIdentityDescriptors; }, { concurrency: 10 }); });