<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Face Mesh Detection</title> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.6.3/css/all.min.css" /> </head> <body> <p><button onclick="start()">Start</button></p> <div> <video id="input" width="320" height="240" autoplay muted playsinline style=" border: solid 1px black; box-sizing: content-box; display: inline-block; " ></video> <span style="position: relative; display: inline-block;"> <span id="loadingicon" class="fa fa-spinner fa-spin" style=" position: absolute; font-size: 100px; margin: 70px 110px; display: none; " ></span> <canvas id="output" width="320" height="240" style="border: solid 1px black; box-sizing: content-box" ></canvas> </span> </div> <script> async function setupCamera(videoElement) { const constraints = { video: { width: 320, height: 240 }, audio: false }; const stream = await navigator.mediaDevices.getUserMedia(constraints); videoElement.srcObject = stream; return new Promise(resolve => { videoElement.onloadedmetadata = () => { videoElement.play(); resolve(); }; }); } function startRender(input, output, model) { const ctx = output.getContext("2d"); async function renderFrame() { requestAnimationFrame(renderFrame); const faces = await model.estimateFaces(input, false, false); console.log(faces); // デバッグ用 ctx.clearRect(0, 0, output.width, output.height); faces.forEach(face => { face.scaledMesh.forEach(xy => { ctx.beginPath(); ctx.arc(xy[0], xy[1], 1, 0, 2 * Math.PI); ctx.fill(); }); }); } renderFrame(); } function loading(onoff) { document.getElementById("loadingicon").style.display = onoff ? "inline" : "none"; } async function start() { const input = document.getElementById("input"); const output = document.getElementById("output"); loading(true); await setupCamera(input); const model = await facemesh.load({ maxFaces: 1 }); startRender(input, output, model); loading(false); } </script> </body> </html>