ロード中

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

WEBサイトでカメラ(WebCam)画像から顔認識して468個の3D顔ランドマークを推定表示する ~Google MediaPipe/face_mesh

WEBサイトでUSBカメラ(WebCam)画像から「Google MediaPipe/face_mesh.js」とJavascriptを使用して顔認識して468個の3D顔ランドマークを推定表示します

カメラ使用を許可してしばらくすると、カメラ映像が表示されます

カメラに顔を映してください。468個の3D顔ランドマークを推定表示します。

ソースコード



<!DOCTYPE html>
<html lang="ja">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0,user-scalable=yes">
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils/control_utils.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/face_mesh.js" crossorigin="anonymous"></script>

  <script type="module">
    let video,can,ctx;
    window.addEventListener('load', async function(event){
      video = document.querySelector('.video');
      can = document.querySelector('.can');
      ctx = can.getContext('2d');

      const faceMesh = new FaceMesh({locateFile: (file) => {
        return `https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${file}`;
      }});
      faceMesh.setOptions({
        maxNumFaces: 1,
        minDetectionConfidence: 0.5,
        minTrackingConfidence: 0.5
      });
      faceMesh.onResults(onResults);

      const camera = new Camera(video, {
        onFrame: async function(){
          await faceMesh.send({image: video});
        },
        width: 640,
        height: 480
      });
      camera.start();
    });

    function onResults(results) {
      ctx.save();
      ctx.clearRect(0, 0, can.width, can.height);
      ctx.drawImage(results.image, 0, 0, can.width, can.height);
      if (results.multiFaceLandmarks) {
        for (const landmarks of results.multiFaceLandmarks) {
          //顔の細かいメッシュを表示
          drawConnectors(ctx, landmarks, FACEMESH_TESSELATION, {color:'#CCC', lineWidth:1});
          //顔の楕円形を表示
          drawConnectors(ctx, landmarks, FACEMESH_FACE_OVAL, {color:'#DDD', lineWidth:2});
          //顔の輪郭(目の輪郭を含む)
          //drawConnectors(ctx, landmarks, FACEMESH_CONTOURS, {color:'#FFF', lineWidth:2});
          //右目
          drawConnectors(ctx, landmarks, FACEMESH_RIGHT_EYE, {color:'#F00', lineWidth:1});
          //右眉
          drawConnectors(ctx, landmarks, FACEMESH_RIGHT_EYEBROW, {color:'#F44', lineWidth:2});
          //左目
          drawConnectors(ctx, landmarks, FACEMESH_LEFT_EYE, {color:'#00F', lineWidth:1});
          //左眉
          drawConnectors(ctx, landmarks, FACEMESH_LEFT_EYEBROW, {color:'#44F', lineWidth:2});
          //唇
          drawConnectors(ctx, landmarks, FACEMESH_LIPS, {color:'#0F0', lineWidth:1});
        }
      }
      ctx.restore();
    }
  </script>
</head>
<body>
  <div class="container">
    <video class="video" style="display:none;"></video>
    <canvas class="can" width="640" height="480" style="transform:scale(-1,1);width:90%;max-width:640px;height:auto;"></canvas>
  </div>
</body>
</html>