기계 학습 "Face-Api"를 사용하여 얼굴 파트에 피카츄 표시

기계 학습(Face-Api)



며칠 전에 '기계학습'을 배웠기 때문에 포켓몬 재료로 뭔가를 만들려고 시도 착오한 이야기입니다.
"몬스터볼에서 피카츄가 튀어나오는 이미지"의 것을 만들려고 했는데, 과연 어느 모델로 실현할 수 있는지 모르고・・・.
그래서 시험에 ml5.js의 "Face-Api"를 사용해 보았습니다.
결과, 무사히 피카츄는 표시할 수 있었지만, 이미지대로는 되지 않았습니다···.
하지만 언젠가 사용할 수 있는 날이 올지도? 라고 생각해, 조금 재미 있었기 때문에 기사로 해 둡니다.

시제품



두 눈의 위치가 확인되면 그 위에 피카츄가 나타납니다. (어쩐지 이미지하고 있었던 것과 다르다···)
피카츄 이미지는 PokeAPI에서 가져온 이미지를 이미지 파일로 호출합니다.


소스 코드



작성에 있어서는, 이하의 기사를 매우 참고로 했습니다.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ピカチュウeyes</title>
  </head>
  <body>
    <h1>ピカチュウeyes</h1>
    <!-- CDNの読み込み -->
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script> -->

    <script>
        let faceapi;
        let video;
        let width = 640;
        let height = 480;
        let ctx;
        let img;

        // Face-Apiのオプション設定
        const detection_options = {
            withLandmarks: true,
            withDescriptors: false,
        }

        // メイン処理
        async function make(){
            img = new Image();
            img.src = 'https://cdn-ak.f.st-hatena.com/images/fotolife/K/Kokano23/20210508/20210508184830.png';
            video = await getVideo();
            let canvas = createCanvas(width, height);
            ctx = canvas.getContext('2d');
            // faceapiモデルのオブジェクト生成
            faceapi = await ml5.faceApi(video, detection_options, modelReady)
        }

        // DOMの読み込み
        window.addEventListener('DOMContentLoaded', function() {
            make();
        });

        // Face-Apiモデルの読み込み
        function modelReady() {
            console.log('ready!')
            faceapi.detect(gotResults)
        }

        // Face-Api呼び出し関数
        function gotResults(err, result) {
            if (err) {
                console.log(err)
                return
            }
        // 自分の映像の情報を取得
         let detections = result;

        // 描画キャンパスを初期化
         ctx.fillStyle = "#000000"
         ctx.fillRect(0,0, width, height);
         ctx.drawImage(video, 0,0, width, height);

        // 自分の映像に描画する処理
          if (detections) {
           if(detections.length > 0){
               drawLandmarks(detections)
                }
            }
        // Face-Apiの再呼び出し
           faceapi.detect(gotResults)
        }

        // Face-Apiで取得した目の位置を特定する処理
        function drawLandmarks(detections){
            for(let i = 0; i < detections.length; i++){
                const leftEye = detections[i].parts.leftEye;
                const rightEye = detections[i].parts.rightEye;
                // 目に画像を描画
                ctx.drawImage(img, leftEye[0].x -10, leftEye[0].y -25, 50, 50);
                ctx.drawImage(img, rightEye[0].x -10, rightEye[0].y -25, 50, 50);
            }
        }

        // Helper Functions
        async function getVideo(){
            // 要素の取得、設定の作成など
            const videoElement = document.createElement('video');
            videoElement.setAttribute("style", "display: none;");
            videoElement.width = width;
            videoElement.height = height;
            document.body.appendChild(videoElement);
            // Webカメラのキャプチャを作成
            const capture = await navigator.mediaDevices.getUserMedia({ video: true })
            videoElement.srcObject = capture;
            videoElement.play();
            return videoElement
        }
        // キャンパスの作成
        function createCanvas(w, h){
            const canvas = document.createElement("canvas");
            canvas.width  = w;
            canvas.height = h;
            document.body.appendChild(canvas);
            return canvas;
        }
    </script>
  </body>
</html>

마지막으로


  • 정말로 하고 싶은 것은, 「Teachable Machine」으로 기계 학습한 몬스터 볼을 검지했을 경우, 몬스터 볼상에 피카츄를 표시시키는 것입니다.
  • 상기를 실현하려면, 「Handpose」를 사용해, 몬스터 볼을 가지는 손의 관절에 피카츄를 표시시키는, 라고 하는 방법이 좋을 것 같습니다. (실현할 수 있으면, 다른 기사로 할 예정입니다)
  • 이번 시제품은, 상상하고 있던 것과는 오히려 다릅니다만, 이것은 이것으로 아이에게 「재미있다!」라고 말해 주었습니다.
  • 시험에 마스크를 착용해 보았는데, 잘 좌표 위치가 인식되지 않았습니다. (공부가되었습니다)
  • 포켓몬을 좋아하는 아이가 계시는 분 등, 꼭 놀아 봐 주세요!
  • 좋은 웹페이지 즐겨찾기