peterbraden / node-opencv

OpenCV Bindings for node.js
MIT License
4.37k stars 857 forks source link

Anime/Cartoon Face Detection #663

Closed jgoralcz closed 4 years ago

jgoralcz commented 4 years ago

Similar with face detection, some people will have a use case for anime/cartoon face detection. I have added an xml file which greatly helps with it.

Below is an example of how I use this (be careful with non-static image if you use the below).

const axios = require('axios');
const cv = require('opencv');
const sharp = require('sharp');
const smartcrop = require('smartcrop-sharp');

const faceDetect = (input, userOptions) => new Promise((resolve, reject) => {
  cv.readImage(input, (err, image) => {
    if (err) return reject(err);
    image.detectObject((userOptions.animeFace) ? cv.ANIME_FACE_CASCADE : cv.FACE_CASCADE, {}, (error, faces) => {
      if (error) return reject(error);
      const boost = faces.map((face) => ({
        x: face.x,
        y: face.y,
        width: face.width,
        height: face.height,
        weight: 1.0,
      }));
      resolve(boost);
    });
  });
});

const execute = async (url, width, height, userOptions }) => {
  const { data: buffer } = await axios.get(url, { responseType: 'arraybuffer' });
  const options = await faceDetect(buffer, userOptions).catch(() => null) || { width, height };
  const { topCrop: crop } = await smartcrop.crop(buffer, options);
  return sharp(buffer)
    .extract({ width: crop.width, height: crop.height, left: crop.x, top: crop.y })
    .resize(width, height)
    .toBuffer();
};

module.exports = execute;