How to detect more than 10 faces in the google vision apis

545 views Asked by At

Hi i am new to google vision apis. I want to detect the faces on the Image ,i am using the node.js. the local image containing more than 10 faces. but vision api returning only 10 faces Detection. Is there any way to detect all the faces using this Vision api. please refer vision node api. and you can take this image as ref enter image description here

Here is my code

function findFaceontheImage(req, res, next) {
        var vision = Vision();
        var inputfile = 'NASA_Astronaut_Group_15.jpg';
        var outputFile = 'out.png';
        vision.faceDetection({source: {filename: inputfile}})
            .then(function (results) {

            const faces = results[0].faceAnnotations;
            console.log('Faces:');

            req.body['faces']=results;
            var numFaces = faces.length;
            console.log('Found ' + numFaces + (numFaces === 1 ? ' face' : ' faces'));

            highlightFaces(inputfile, faces, outputFile, Canvas, function (err) {
                if (err) {
                    next()
                }
                console.log("Finished!");
                next()
            });


        })
        .catch(function (err) {
            console.error('ERROR:', err);
        });

}

function highlightFaces(inputFile, faces, outputFile, Canvas, callback) {
    fs.readFile(inputFile, function (err, image) {
        if (err) {
            return callback(err);
        }

        var Image = Canvas.Image;
        // Open the original image into a canvas
        var img = new Image();
        img.src = image;
        var canvas = new Canvas(img.width, img.height);
        var context = canvas.getContext("2d");
        context.drawImage(img, 0, 0, img.width, img.height);

        // Now draw boxes around all the faces
        context.strokeStyle = "rgba(0,255,0,0.8)";
        context.lineWidth = "5";

        faces.forEach(function (face) {
            context.beginPath();
            var origX = 0;
            var origY = 0;
            face.boundingPoly.vertices.forEach(function (bounds, i) {
                if (i === 0) {
                    origX = bounds.x;
                    origY = bounds.y;
                }
                context.lineTo(bounds.x, bounds.y);
            });
            context.lineTo(origX, origY);
            context.stroke();
        });

        // Write the result to a file
        console.log("Writing to file " + outputFile);
        var writeStream = fs.createWriteStream(outputFile);
        var pngStream = canvas.pngStream();

        pngStream.on("data", function (chunk) {
            writeStream.write(chunk);
        });
        pngStream.on("error", console.log);
        pngStream.on("end", callback);
    });
}
2

There are 2 answers

0
Nakilon On

Just in case noone will come up with solution that would force API to return more results, a pseudocode:

def process(image)
  faces = process image
  return faces if faces.size < 10
  split image into two a bit overlapping half1 and half2
  # we do overlapping because splitting may split a face
  a = process(half1)
  b = process(half2)
  return a + b - intersection(a + b)

The intersection function should throw out those images that are on the same (taking in mind the possible +/-few pixel errors) coordinates plus the shift that we had between half1 and half2 withing the image.

0
natchapolt On

In case there're other people who's still struggling on this topic.

With the Node.js Client Library, you can pass the ImprovedRequest object to the client.faceDetection(..) method instead of using the filepath or imageuri.

For example, in my case, I want the api to process an image in my GCS. So, instead of placing the imageuri as string. I'd do something like below.

import { protos } from '@google-cloud/vision';

// BEFORE
const [result] = await CLIENT.faceDetection(`gs://${bucketName}/${filePath}`);

// AFTER
const [result] = await CLIENT.faceDetection({
  image: { 
    source: { imageUri: `gs://${bucketName}/${filePath}` } 
  },
  features: [
    {
      maxResults: 100,
      type: protos.google.cloud.vision.v1.Feature.Type.FACE_DETECTION,
    },
  ],
});