Face.com – une API gratuite de reconnaissance faciale

Voila une API relativement intéressante, même si les possibilités qu’elle offre font un peu froid dans le dos.

Face.com vous propose une API permettant de reconnaître tous types de visages sur tous types de photos et d’y appliquer une action.

Cela peux s’étendre du simple marquage automatique de photos, à l’ajout d’une moustache automatique sur tous les portraits, l’échange de portraits, ou plus fou encore : la recherche de personnes sur le net (informations, photos…) simplement à partir d’un bout de visage flou et scanné à l’arrache (vous le sentez venir le côté angoissant?).

Lien vers l’api : http://developers.face.com
Lien vers le site : http://www.face.com

5 réactions au sujet de « Face.com – une API gratuite de reconnaissance faciale »

  1. quelqu'un Réponse

    Bonjour ,
    Le commentaire que je me permet de vous laisser réuni quelques questions simples :
    Puis-je grace a une photo retrouver la personne que concerne la photo ??
    Quel genre d’informations puis-je obtenir sur cette personne dans ces cas là?

    Merci de bien vouloir me recontacter afin de donner des réponses à mes questions.

    Quelqu’un .

  2. TonJuju Réponse

    Tu n’as plus à t’inquiéter, racheté par Facebook, Fermé par Facebook. Ils veulent se la garder pour eux.

  3. Deter Réponse

    Bonjour,
    j’aimerais savoir si cette api est capable de trouver des similitudes entre des visages différents. Par exemple si je veux trouver mon sosie ou quelqu’un qui me ressemble beaucoup parmi une grande base de données ? et sinon , connaissez-vous une autre API étant capable d’une telle chose ?

    Merci d’avance !

    • youssef Réponse

      Oui c’est possible. Voici la bibliothèque à utiliser en javascript

      (function(_this){
      ‘use strict’;
      var pixelTransparency = 1;
      var errorPixelColor = { // Color for Error Pixels. Between 0 and 255.
      red: 255,
      green: 0,
      blue: 255,
      alpha: 255
      };

      function colorsDistance(c1, c2){
      return (Math.abs(c1.r – c2.r) + Math.abs(c1.g – c2.g) + Math.abs(c1.b – c2.b))/3;
      }

      var errorPixelTransform = {
      flat : function (d1, d2){
      return {
      r: errorPixelColor.red,
      g: errorPixelColor.green,
      b: errorPixelColor.blue,
      a: errorPixelColor.alpha
      }
      },
      movement: function (d1, d2){
      return {
      r: ((d2.r*(errorPixelColor.red/255)) + errorPixelColor.red)/2,
      g: ((d2.g*(errorPixelColor.green/255)) + errorPixelColor.green)/2,
      b: ((d2.b*(errorPixelColor.blue/255)) + errorPixelColor.blue)/2,
      a: d2.a
      }
      },
      flatDifferenceIntensity: function (d1, d2){
      return {
      r: errorPixelColor.red,
      g: errorPixelColor.green,
      b: errorPixelColor.blue,
      a: colorsDistance(d1, d2)
      }
      },
      movementDifferenceIntensity: function (d1, d2){
      var ratio = colorsDistance(d1, d2)/255 * 0.8;
      return {
      r: ((1-ratio)*(d2.r*(errorPixelColor.red/255)) + ratio*errorPixelColor.red),
      g: ((1-ratio)*(d2.g*(errorPixelColor.green/255)) + ratio*errorPixelColor.green),
      b: ((1-ratio)*(d2.b*(errorPixelColor.blue/255)) + ratio*errorPixelColor.blue),
      a: d2.a
      }
      }
      };

      var errorPixelTransformer = errorPixelTransform.flat;

      var largeImageThreshold = 1200;

      var httpRegex = /^https?:\/\//;
      var documentDomainRegex = new RegExp(‘^https?://’ + document.domain);

      _this[‘resemble’] = function( fileData ){

      var data = {};
      var images = [];
      var updateCallbackArray = [];

      var tolerance = { // between 0 and 255
      red: 16,
      green: 16,
      blue: 16,
      alpha: 16,
      minBrightness: 16,
      maxBrightness: 240
      };

      var ignoreAntialiasing = false;
      var ignoreColors = false;

      function triggerDataUpdate(){
      var len = updateCallbackArray.length;
      var i;
      for(i=0;i<len;i++){
      if (typeof updateCallbackArray[i] === 'function'){
      updateCallbackArray[i](data);
      }
      }
      }

      function loop(x, y, callback){
      var i,j;

      for (i=0;i<x;i++){
      for (j=0;j<y;j++){
      callback(i, j);
      }
      }
      }

      function parseImage(sourceImageData, width, height){

      var pixelCount = 0;
      var redTotal = 0;
      var greenTotal = 0;
      var blueTotal = 0;
      var brightnessTotal = 0;

      loop(height, width, function(verticalPos, horizontalPos){
      var offset = (verticalPos*width + horizontalPos) * 4;
      var red = sourceImageData[offset];
      var green = sourceImageData[offset + 1];
      var blue = sourceImageData[offset + 2];
      var brightness = getBrightness(red,green,blue);
      pixelCount++;
      redTotal += red / 255 * 100;
      greenTotal += green / 255 * 100;
      blueTotal += blue / 255 * 100;
      brightnessTotal += brightness / 255 * 100;
      });

      data.red = Math.floor(redTotal / pixelCount);
      data.green = Math.floor(greenTotal / pixelCount);
      data.blue = Math.floor(blueTotal / pixelCount);
      data.brightness = Math.floor(brightnessTotal / pixelCount);

      triggerDataUpdate();
      }

      function loadImageData( fileData, callback ){
      var fileReader;
      var hiddenImage = new Image();

      if (httpRegex.test(fileData) && !documentDomainRegex.test(fileData)) {
      hiddenImage.setAttribute('crossorigin', 'anonymous');
      }

      hiddenImage.onload = function() {

      var hiddenCanvas = document.createElement('canvas');
      var imageData;
      var width = hiddenImage.width;
      var height = hiddenImage.height;

      hiddenCanvas.width = width;
      hiddenCanvas.height = height;
      hiddenCanvas.getContext('2d').drawImage(hiddenImage, 0, 0, width, height);
      imageData = hiddenCanvas.getContext('2d').getImageData(0, 0, width, height);

      images.push(imageData);

      callback(imageData, width, height);
      };

      if (typeof fileData === 'string') {
      hiddenImage.src = fileData;
      if (hiddenImage.complete) {
      hiddenImage.onload();
      }
      } else if (typeof fileData.data !== 'undefined'
      && typeof fileData.width === 'number'
      && typeof fileData.height === 'number') {
      images.push(fileData);
      callback(fileData, fileData.width, fileData.height);
      } else {
      fileReader = new FileReader();
      fileReader.onload = function (event) {
      hiddenImage.src = event.target.result;
      };
      fileReader.readAsDataURL(fileData);
      }
      }

      function isColorSimilar(a, b, color){

      var absDiff = Math.abs(a – b);

      if(typeof a === 'undefined'){
      return false;
      }
      if(typeof b === 'undefined'){
      return false;
      }

      if(a === b){
      return true;
      } else if ( absDiff tolerance.maxBrightness;
      }

      function getHue(r,g,b){

      r = r / 255;
      g = g / 255;
      b = b / 255;
      var max = Math.max(r, g, b), min = Math.min(r, g, b);
      var h;
      var d;

      if (max == min){
      h = 0; // achromatic
      } else{
      d = max – min;
      switch(max){
      case r: h = (g – b) / d + (g < b ? 6 : 0); break;
      case g: h = (b – r) / d + 2; break;
      case b: h = (r – g) / d + 4; break;
      }
      h /= 6;
      }

      return h;
      }

      function isAntialiased(sourcePix, data, cacheSet, verticalPos, horizontalPos, width){
      var offset;
      var targetPix;
      var distance = 1;
      var i;
      var j;
      var hasHighContrastSibling = 0;
      var hasSiblingWithDifferentHue = 0;
      var hasEquivilantSibling = 0;

      addHueInfo(sourcePix);

      for (i = distance*-1; i <= distance; i++){
      for (j = distance*-1; j 0.3 ){
      hasSiblingWithDifferentHue++;
      }

      if( hasSiblingWithDifferentHue > 1 || hasHighContrastSibling > 1){
      return true;
      }
      }
      }
      }

      if(hasEquivilantSibling largeImageThreshold || height > largeImageThreshold)){
      skip = 6;
      }
      loop(height, width, function(verticalPos, horizontalPos){
      if(skip){ // only skip if the image isn’t small
      if(verticalPos % skip === 0 || horizontalPos % skip === 0){
      return;
      }
      }
      var offset = (verticalPos*width + horizontalPos) * 4;
      var pixel1 = getPixelInfo(data1, offset, 1);
      var pixel2 = getPixelInfo(data2, offset, 2);

      if(pixel1 === null || pixel2 === null){
      return;
      }

      if (ignoreColors){
      addBrightnessInfo(pixel1);
      addBrightnessInfo(pixel2);
      if( isPixelBrightnessSimilar(pixel1, pixel2) ){
      copyGrayScalePixel(targetPix, offset, pixel2);
      } else {
      errorPixel(targetPix, offset, pixel1, pixel2);
      mismatchCount++;
      }
      return;
      }

      if( isRGBSimilar(pixel1, pixel2) ){
      copyPixel(targetPix, offset, pixel1, pixel2);
      } else if( ignoreAntialiasing && (
      addBrightnessInfo(pixel1), // jit pixel info augmentation looks a little weird, sorry.
      addBrightnessInfo(pixel2),
      isAntialiased(pixel1, data1, 1, verticalPos, horizontalPos, width) ||
      isAntialiased(pixel2, data2, 2, verticalPos, horizontalPos, width)
      )){

      if( isPixelBrightnessSimilar(pixel1, pixel2) ){
      copyGrayScalePixel(targetPix, offset, pixel2);
      } else {
      errorPixel(targetPix, offset, pixel1, pixel2);
      mismatchCount++;
      }
      } else {
      errorPixel(targetPix, offset, pixel1, pixel2);
      mismatchCount++;
      }
      });

      data.misMatchPercentage = (mismatchCount / (height*width) * 100).toFixed(2);
      data.analysisTime = Date.now() – time;
      data.getImageDataUrl = function(text){
      var barHeight = 0;
      if(text){
      barHeight = addLabel(text,context,hiddenCanvas);
      }
      context.putImageData(imgd, 0, barHeight);
      return hiddenCanvas.toDataURL(“image/png”);
      };
      }

      function addLabel(text, context, hiddenCanvas){
      var textPadding = 2;
      context.font = ’12px sans-serif’;
      var textWidth = context.measureText(text).width + textPadding*2;
      var barHeight = 22;
      if(textWidth > hiddenCanvas.width){
      hiddenCanvas.width = textWidth;
      }

      hiddenCanvas.height += barHeight;
      context.fillStyle = “#666”;
      context.fillRect(0,0,hiddenCanvas.width,barHeight -4);
      context.fillStyle = “#fff”;
      context.fillRect(0,barHeight -4,hiddenCanvas.width, 4);
      context.fillStyle = “#fff”;
      context.textBaseline = “top”;
      context.font = ’12px sans-serif’;
      context.fillText(text, textPadding, 1);
      return barHeight;
      }

      function normalise(img, w, h){
      var c;
      var context;
      if(img.height < h || img.width images[1].width ? images[0].width : images[1].width;
      height = images[0].height > images[1].height ? images[0].height : images[1].height;

      if( (images[0].width === images[1].width) && (images[0].height === images[1].height) ){
      data.isSameDimensions = true;
      } else {
      data.isSameDimensions = false;
      }
      data.dimensionDifference = { width: images[0].width – images[1].width, height: images[0].height – images[1].height };
      analyseImages( normalise(images[0],width, height), normalise(images[1],width, height), width, height);
      triggerDataUpdate();
      }
      }
      images = [];
      loadImageData(one, onceWeHaveBoth);
      loadImageData(two, onceWeHaveBoth);
      }

      function getCompareApi(param){
      var secondFileData,
      hasMethod = typeof param === ‘function’;
      if( !hasMethod ){
      // assume it’s file data
      secondFileData = param;
      }

      var self = {
      ignoreNothing: function(){
      tolerance.red = 16;
      tolerance.green = 16;
      tolerance.blue = 16;
      tolerance.alpha = 16;
      tolerance.minBrightness = 16;
      tolerance.maxBrightness = 240;
      ignoreAntialiasing = false;
      ignoreColors = false;
      if(hasMethod) { param(); }
      return self;
      },
      ignoreAntialiasing: function(){
      tolerance.red = 32;
      tolerance.green = 32;
      tolerance.blue = 32;
      tolerance.alpha = 32;
      tolerance.minBrightness = 64;
      tolerance.maxBrightness = 96;
      ignoreAntialiasing = true;
      ignoreColors = false;
      if(hasMethod) { param(); }
      return self;
      },
      ignoreColors: function(){
      tolerance.alpha = 16;
      tolerance.minBrightness = 16;
      tolerance.maxBrightness = 240;
      ignoreAntialiasing = false;
      ignoreColors = true;
      if(hasMethod) { param(); }
      return self;
      },
      repaint: function(){
      if(hasMethod) { param(); }
      return self;
      },
      onComplete: function( callback ){
      updateCallbackArray.push(callback);
      var wrapper = function(){
      compare(fileData, secondFileData);
      };
      wrapper();
      return getCompareApi(wrapper);
      }
      };
      return self;
      }

      return {
      onComplete: function( callback ){
      updateCallbackArray.push(callback);
      loadImageData(fileData, function(imageData, width, height){
      parseImage(imageData.data, width, height);
      });
      },
      compareTo: function(secondFileData){
      return getCompareApi(secondFileData);
      }
      };
      };

      _this[‘resemble’].outputSettings = function(options){
      var key;
      var undefined;
      if(options.errorColor){
      for (key in options.errorColor) {
      errorPixelColor[key] = options.errorColor[key] === undefined ? errorPixelColor[key] : options.errorColor[key];
      }
      }
      if(options.errorType && errorPixelTransform[options.errorType] ){
      errorPixelTransformer = errorPixelTransform[options.errorType];
      }
      pixelTransparency = isNaN(Number(options.transparency)) ? pixelTransparency : options.transparency;
      if (options.largeImageThreshold !== undefined) {
      largeImageThreshold = options.largeImageThreshold;
      }
      return this;
      };

      }(this));

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.