I'm using face-api.js Javascript API to develop a web app that user uploads her/his picture and we want to detect faces in the picture.
On the other hand I used VGGface 16 model json formatted to predict that user uploaded image is similar to which celebrity.
following are my javascript codes:
const MODEL_URL = '../faceapi_models'
Promise.all([
faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL),
faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
])
.then((val) => {
console.log('val')
})
.catch((err) => {
console.log(err)
})
let model
async function loadModel() {
model = await tf.loadLayersModel('../web_model/vgg_model.json');
}
loadModel()
.then((val) => {
console.log('Model is Loaded');
})
.catch((err) => {
console.log('Model Not Load : ' + err)
})
let croppedImage = null;
const user_pic = document.getElementById('user_pic')
const preview = document.getElementById('preview')
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
window.onload = function () {
canvas.width = preview.width;
canvas.height = preview.height;
ctx.drawImage(preview, 0, 0);
};
preview.onclick = () => user_pic.click()
user_pic.addEventListener('change', () => {
const reader = new FileReader()
reader.onload = (e) => {
const img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
};
img.src = e.target.result;
}
reader.readAsDataURL(user_pic.files[0]);
detectFaces(user_pic.files[0])
})
async function detectFaces(input) {
let imgURL = URL.createObjectURL(input)
const imgElement = new Image()
imgElement.src = imgURL
const results = await faceapi.detectAllFaces(imgElement)
.then(results => {
if (Array.isArray(results) && results.forEach) {
results.forEach(result => {
// console.log(result)
const {x, y, width, height} = result.box;
const xInt = Math.floor(x);
const yInt = Math.floor(y);
const widthInt = Math.floor(width);
const heightInt = Math.floor(height);
const crop = ctx.getImageData(xInt, yInt, widthInt, heightInt);
croppedImage = new ImageData(crop.data, widthInt, heightInt);
const input = tf.browser.fromPixels(croppedImage);
const resizedImage = tf.image.resizeBilinear(input, [224, 224]);
const inputTensor = resizedImage.expandDims(0);
// Make predictions
model.predict(inputTensor).data()
.then(predictions =>{
const predictionsArray = Array.from(predictions)
const celebrityIndex = predictionsArray.indexOf(Math.max(...predictionsArray));
console.log(celebrityIndex)
/*const celebrityName = classNames[celebrityIndex] || 'Unknown';
console.log(celebrityName);*/
//Display the results
/*const resultDisplay = document.getElementById('result');
resultDisplay.innerHTML = `Most similar celebrity: ${celebrityName}`;*/
});
});
} else {
console.error('Results is not an array or does not have a forEach function.');
}
});
}
All things work fine and I get index of predicted celebrity. but now I do not know how to get name of that celebrity.
in python example code we use utils.decode_predictions
method like this :
predict = vggface.predict(samples)
print(predict)
output = utils.decode_predictions(predict)
print(output)
# for result in output[0]:
# print('%s: %.3f%%' % (result[0], result[1]*100))
prediction = output[0][0][0].replace("b'", "").replace("'","")
prediction
And it return name of celebrity that have most similarity to image.
But I do not know how can I implement this in tensorflow js ?