ロード中
しばらくお待ちください

トップへ(mam-mam.net/)

Javascriptで顔写真から個別にマッチングして顔認識して顔識別する(face-api.js)

検索:

Javascriptで顔写真から個別にマッチングして顔認識して顔識別する(face-api.js使用)
※写真は「ぱたくそ」様(https://www.pakutaso.com/)より使用させていただいています。

以下2枚の顔写真を登録して、写真から個別に顔識別します


眼鏡の男性

サラリーマン

顔識別テスト1


顔識別テスト2


顔識別テスト3



ソースコード



<div style="display:flex;flex-wrap:wrap;">
  <div>
    <img src="./imgs/face-api/img1.jpg" id="img1" width="600" height="400">
    <br>
    <button onclick="descript('img1')">認識する</button>
  </div>
  <div>
    <canvas id="preview_img1" style="width:400px;max-width:100%;height:auto;" width="600" height="600"></canvas>
  </div>
</div>

<script>
var faceMatcher=[];//顔画像から特徴点を取り出した値を入れる
var detectImg=[];
var detectImgURL=["./imgs/face-api/face1.jpg","./imgs/face-api/face2.jpg"];
var detectImgLabel=["眼鏡の男性","サラリーマン"];

async function loadImage(src){
  return new Promise(function(resolve,reject){
    let img=new Image();
    img.onload=function(){resolve(img);}
    img.onerror=function(e){reject(e);}
    img.src=src;
  });
}

window.addEventListener('load',async function(event){
  await Promise.all([
    //SsdMobilenetv1Modelを使用する
    faceapi.nets.ssdMobilenetv1.loadFromUri('./models'),
    //faceLandmark68Netを使用する
    faceapi.nets.faceLandmark68Net.loadFromUri("./models"),
    //faceRecognitionNetを使用する
    faceapi.nets.faceRecognitionNet.loadFromUri("./models")
  ]);
  
  
  //顔識別させたい複数画像を登録する
  detectImg=await Promise.all(detectImgURL.map(loadImage));
  for(let i=0;i<detectImg.length;i++){
    let singleResult=await faceapi.detectAllFaces(detectImg[i]).withFaceLandmarks().withFaceDescriptors();
    if(singleResult.length>0){
      const labeledDescriptors = [
        new faceapi.LabeledFaceDescriptors(
          detectImgLabel[i],//ラベルを設定する
          [singleResult[0].descriptor]
        ),
      ];
      faceMatcher[i] = new faceapi.FaceMatcher(labeledDescriptors);
    }
  }
});
function descript(id){
  let img=document.getElementById(id);
  faceapi.detectAllFaces(id, new faceapi.SsdMobilenetv1Options()).withFaceLandmarks().withFaceDescriptors().then(
    function(result){
      let can=document.getElementById("preview_"+id);
      let ctx=can.getContext("2d",{willReadFrequently:true});
      let family=
        'Verdana,Roboto,"Droid Sans","游ゴシック",YuGothic,"メイリオ",Meiryo,'+
        '"ヒラギノ角ゴ ProN W3","Hiragino Kaku Gothic ProN","MS Pゴシック",sans-serif';
      ctx.font="bold 24px "+family;
      ctx.fillStyle='rgba(0,0,255,1)';

      ctx.drawImage(img,0,0);
      if(faceMatcher!=null && result.length>0){
        for(i=0;i<result.length;i++){
          for(let j=0;j<faceMatcher.length;j++){
            let bestMatch = faceMatcher[j].findBestMatch(result[i].descriptor);
            if(bestMatch._distance<0.55){
              //console.log(bestMatch);
              ctx.lineWidth=4;
              ctx.strokeStyle="#ff0000";
              ctx.strokeRect(
                result[i].detection.box.x,
                result[i].detection.box.y,
                result[i].detection.box.width,
                result[i].detection.box.height
              );
              /*
              ctx.moveTo(result[i].detection.box.x, result[i].detection.box.y);
              ctx.lineTo(result[i].detection.box.x+0, result[i].detection.box.y+result[i].detection.box.height);
              ctx.lineTo(result[i].detection.box.x+result[i].detection.box.width, result[i].detection.box.y+result[i].detection.box.height);
              ctx.lineTo(result[i].detection.box.x+result[i].detection.box.width, result[i].detection.box.y+0);
              ctx.lineTo(result[i].detection.box.x+0, result[i].detection.box.y+0);
              ctx.stroke();
              */

              //該当するラベルを表示する
              ctx.fillText(
                bestMatch.label,
                result[i].detection.box.x,
                result[i].detection.box.y+result[i].detection.box.height+20
              );
            }
          }
        }
      }

    }
  );
}
</script>

使用したライブラリ

face-api.js(https://github.com/justadudewhohacks/face-api.js)を使用させていただきました。
face-api.jsのライセンス情報
MIT License
Copyright (c) 2018 Vincent Mühler