ブラウザだけで表情認識をできる「face-api.js」を使います。クラウドAPIサービスと違い、課金の心配はありません。今回は笑顔のスコアをメーターで表すWebアプリを作ってみます。
笑顔メーター
カメラ映像から顔を検出し、笑顔のスコアをメーターで表すWebアプリです。
上のサンプルでは、カメラではなくフリーの動画素材を使っています。pixabay.comに掲載されていた笑顔の少年を使いました。
少年は軽々、笑顔100%のスコアをたたき出しています。
カメラに向かって自分の顔で試したときは、けっこう頑張らないと笑顔100%のスコアは出ませんでした・・・。
よい、笑顔のトレニンーグになります。
face-api.jsを使うには?
「face-api.js – ブラウザでの顔認識を行うJavaScript API」を参考にさせて頂きました。導入から顔認識モデルの説明に至るまで、詳細な情報が掲載されています。
私は、face-api.jsのファイルの中から、必要なものだけ自分の開発環境に移しました。下記の構成で配置しています。
1 2 3 4 5 6 |
face/ ├ js/ │ ├ main.js │ ├ face-api.min.js(face-api.js/dist/から持ってくる) │ └ weights/(face-api.js/weightsから持ってくる) └index.html |
main.jsとindex.htmlに、コードを書いていきます。
face/index.htmlのコード(HTMLとCSS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<html> <head> <title>笑顔メーター</title> <style> #cameraArea { position: relative; max-width: 640px; margin: 0 auto; } #canvas { position: absolute; left: 0; } #emoticonBar { position: absolute; top: 0; right: -30px; width: 40px; height: 480px; border-right: #DDD solid 6px; } #emoticon { position: absolute; bottom: 0; right: -24px; width: 40px; height: 40px; border-radius: 50%; background-color: #CCC; text-align: center; font-size: 24px; line-height: 40px; transform: rotate(90deg); transition: bottom 0.3s; } </style> </head> <body> <main> <div id="cameraArea"> <video id="camera" width="640" height="480" playsinline muted autoplay></video> <canvas id="canvas"></canvas> <div id="emoticonBar"><span id="emoticon">:|</span></div> </div> <script src="js/face-api.min.js"></script> <script src="js/main.js"></script> </body> </html> |
face/js/main.jsのコード(JavaScript)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
const FACE = {}; FACE.EXPRESSION = () => { const cameraArea = document.getElementById('cameraArea'), camera = document.getElementById('camera'), canvas = document.getElementById('canvas'), emoticon = document.getElementById('emoticon'), ctx = canvas.getContext('2d'), canvasW = 640, canvasH = 480, intervalTime = 500, emoticonTxt = [':)',':|']; const init = async () => { setCanvas(); setCamera(); await faceapi.nets.tinyFaceDetector.load("js/weights/"); await faceapi.nets.faceExpressionNet.load("js/weights/"); }, setCanvas = () => { canvas.width = canvasW; canvas.height = canvasH; }, setCamera = async () => { var constraints = { audio: false, video: { width: canvasW, height: canvasH, facingMode: 'user' } }; await navigator.mediaDevices.getUserMedia(constraints) .then((stream) => { camera.srcObject = stream; camera.onloadedmetadata = (e) => { playCamera(); }; }) .catch((err) => { console.log(err.name + ': ' + err.message); }); }, playCamera = () => { camera.play(); setInterval(async () => { canvas.getContext('2d').clearRect(0, 0, canvasW, canvasH); checkFace(); }, intervalTime); }, checkFace = async () => { let faceData = await faceapi.detectAllFaces( camera, new faceapi.TinyFaceDetectorOptions() ).withFaceExpressions(); if(faceData.length){ const setDetection = () => { let box = faceData[0].detection.box; x = box.x, y = box.y, w = box.width, h = box.height; ctx.beginPath(); ctx.rect(x, y, w, h); ctx.strokeStyle = '#76FF03'; ctx.lineWidth = 2; ctx.stroke(); }, setExpressions = () => { let happy = faceData[0].expressions.happy, color = happy * 150 + 100; emoticon.style.bottom = (canvasH - 40) * happy + 'px'; emoticon.style.backgroundColor = `rgb(${color}, ${color}, 100)`; if(happy > 0.5){ emoticon.innerHTML = emoticonTxt[0]; }else{ emoticon.innerHTML = emoticonTxt[1]; } }; setDetection(); setExpressions(); } }; init(); }; FACE.EXPRESSION(); |
今さらながら、ES6のJavaScriptを初めて書きました。文法が怪しいのでご注意ください。
表情解析は、端末負担を軽減させるため、0.5秒おきに行います。
もし、顔の検出ができたら□で囲い、さらに笑顔のスコアを取得して、右の笑顔メーターに反映させます。
ブラウザで表情解析が完結するお手軽さが、素晴らしいです。
余談:笑顔でクッキーにスタンプを押したい
笑顔を認識したくなった経緯です。
昨日視線操作クッキースタンプというものを作りました。重度障害者が目で操作して、クッキーにスタンプを押す装置です。今度は目ではなく、表情で操作できるようにしました。
笑顔をトリガーにして、クッキーにスマイルスタンプを押します。
笑顔でクッキーを作れればと。