The default face-api.js uses only one image as reference for face recognition, but through my tests I noticed a pretty high error gap. So I was wondering, how can I manage to increase the number of reference images, in order to reduce the error gap?
Assuming my images are in the imgs/ folder, how can I do this?
Here's my project folder :
Here's the faceRecognition.ts file :
import * as faceapi from 'face-api.js';
import { canvas, faceDetectionNet, faceDetectionOptions, saveFile } from './commons';
const REFERENCE_IMAGE = '../../imgs/test1.jpeg'
const QUERY_IMAGE = '../../test/test.jpeg'
// i want to have many images for the REFERENCE_IMAGE
// in folder imgs, i have 5 images in a want to use all five images for increase
// the result. Actually i have some bad prediction when i use only one image
async function run() {
await faceDetectionNet.loadFromDisk('../../weights')
await faceapi.nets.faceLandmark68Net.loadFromDisk('../../weights')
await faceapi.nets.faceRecognitionNet.loadFromDisk('../../weights')
const referenceImage = await canvas.loadImage(REFERENCE_IMAGE)
const queryImage = await canvas.loadImage(QUERY_IMAGE)
const resultsRef = await faceapi.detectAllFaces(referenceImage, faceDetectionOptions)
.withFaceLandmarks()
.withFaceDescriptors()
const resultsQuery = await faceapi.detectAllFaces(queryImage, faceDetectionOptions)
.withFaceLandmarks()
.withFaceDescriptors()
const faceMatcher = new faceapi.FaceMatcher(resultsRef)
const labels = faceMatcher.labeledDescriptors
.map(ld => ld.label)
const refDrawBoxes = resultsRef
.map(res => res.detection.box)
.map((box, i) => new faceapi.draw.DrawBox(box, { label: labels[i] }))
const outRef = faceapi.createCanvasFromMedia(referenceImage)
refDrawBoxes.forEach(drawBox => drawBox.draw(outRef))
saveFile('referenceImage.jpg', (outRef as any).toBuffer('image/jpeg'))
const queryDrawBoxes = resultsQuery.map(res => {
const bestMatch = faceMatcher.findBestMatch(res.descriptor)
return new faceapi.draw.DrawBox(res.detection.box, { label: bestMatch.toString() })
})
const outQuery = faceapi.createCanvasFromMedia(queryImage)
queryDrawBoxes.forEach(drawBox => drawBox.draw(outQuery))
saveFile('queryImage.jpg', (outQuery as any).toBuffer('image/jpeg'))
}
run()
Can anyone help ?
const path = require('path')
import * as faceapi from 'face-api.js';
import { canvas, faceDetectionNet, faceDetectionOptions, saveFile } from './commons';
async function start() {
await faceDetectionNet.loadFromDisk('../../weights')
await faceapi.nets.faceLandmark68Net.loadFromDisk('../../weights')
await faceapi.nets.faceRecognitionNet.loadFromDisk('../../weights')
const labeledFaceDescriptors = await loadLabeledImages()
const faceMatcher = new faceapi.FaceMatcher(labeledFaceDescriptors, 0.6)
const queryImage = await canvas.loadImage(`test/test.jpeg`)
//absolute link to image
const detections = await faceapi.detectAllFaces(queryImage ).withFaceLandmarks().withFaceDescriptors()
const queryDrawBoxes = detections.map(res => {
const bestMatch = faceMatcher.findBestMatch(res.descriptor)
return new faceapi.draw.DrawBox(res.detection.box, { label: bestMatch.toString() })
})
const outQuery = faceapi.createCanvasFromMedia(queryImage)
queryDrawBoxes.forEach(drawBox => drawBox.draw(outQuery))
saveFile('queryImage.jpg', (outQuery as any).toBuffer('image/jpeg'))
console.log('done, saved results to out/queryImage.jpg')
}
function loadLabeledImages() {
const labels = ['imgs']
return Promise.all(
labels.map(async label => {
const descriptions = []
for (let i = 1; i <= 5; i++) {
const img = await canvas.loadImage(`/imgs/test${i}.jpeg` )
// for example if you are test1 , test2, etc. like image's names
const detections = await faceapi.detectSingleFace(img).withFaceLandmarks().withFaceDescriptor()
descriptions.push(detections.descriptor)
}
return new faceapi.LabeledFaceDescriptors(label, descriptions)
})
)
}
start()