Как я могу заставить консоль регистрировать определенную ключевую точку c, то есть нос, используя faceme sh. js (tensorflow)? - PullRequest
0 голосов
/ 07 августа 2020
<head>

    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/facemesh"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl"></script>
    <script>

    /* running facemesh code */
    async function get_facemesh()
    {

        // load HTML canvas
        var canvas = document.getElementById("facemesh");
        var draw = canvas.getContext("2d");

        // get video stream
        const stream = document.getElementById("movie");

        // load facemesh model
        const model = await facemesh.load(maxFaces=1);

        // process input stream frame by frame
        while(1)
        {
            // fill canvas with black background
            draw.fillStyle = "black";
            draw.fillRect(0, 0, canvas.width, canvas.height);

            // detect faces
            const faces = await model.estimateFaces(stream);

            if(faces.length != 0)
            {
                // loop through faces array to capture multiple faces
                var mesh = faces[0].scaledMesh;

                console.log(mesh);

                /* highlight facial landmark points on canvas board */
                draw.fillStyle = "#00FF00";

                for(i=0; i< mesh.length; i++)
                {
                    var [x, y, z] = mesh[i];
                    draw.fillRect(Math.round(x), Math.round(y), 2, 2);
                }
            }
            else
            {
                console.log(`no faces detected..`);
            }

            // loop to process the next frame
            await tf.nextFrame();
        }
    }
    </script>
</head>

<body>

    <video width=640 height=480 autoplay id="movie"> </video>
    <canvas width=640 height=480 id="facemesh"> </canvas>

    <br>
    <script>

        // capture live video stream from web camera
        video = document.getElementById("movie");
        if(navigator.mediaDevices.getUserMedia)
        {
                navigator.mediaDevices.getUserMedia({video: true})
                    .then(function (stream) {video.srcObject = stream; });
        }

        // run face-mesh model once the video is ready for processing
        main();

        function main()
        {
            // check if the video is loaded and ready for processing
            if(video.readyState == 4)
            {
                console.log("video is ready for processing..");
                get_facemesh();
            }
            else
            {
                console.log("nope, not loaded yet..");
                setTimeout(main, 1000/30);
            }
        }
       
    </script>
</body>

</html>

Вот пример кода. Этот код записывает в консоль все ориентиры на лице, но я пытаюсь заставить его записывать ориентир только на носу. Как мне это сделать?

Вот ссылка на его github: https://github.com/tensorflow/tfjs-models/tree/master/facemesh. А вот ссылка на лицевые ориентиры: https://raw.githubusercontent.com/tensorflow/tfjs-models/master/facemesh/mesh_map.jpg. Вот что я пробовал: я попытался установить переменную носа равной getUVCoords (19). var nose = getUVCoords(19) Затем я заменил console.log(mesh) на console.log(nose). Это не работает. Это предотвратило даже запуск тензорного потока. Буду признателен за любую помощь в этом вопросе.

1 Ответ

0 голосов
/ 10 августа 2020

Кажется, вы перезаписывали свой холст после того, как нарисовали точки. Вот код, который работает для меня при написании вашей функции get_faceme sh:

async function get_facemesh()

{

    // load HTML canvas

    var canvas = document.getElementById("facemesh");

    var draw = canvas.getContext("2d");

    // get video stream

    const stream = document.getElementById("movie");

    // load facemesh model

    const model = await facemesh.load(maxFaces=1);

    // process input stream frame by frame
    while(1)

    {
        // detect faces

        const faces = await model.estimateFaces(stream);

        if(faces.length > 0)

        {
            // Reset frame  
          draw.fillStyle = "black";
            draw.fillRect(0, 0, canvas.width, canvas.height);
            // loop through faces array to capture multiple faces

            var mesh = faces[0].scaledMesh;

            /* highlight facial landmark points on canvas board */

            draw.fillStyle = "#00FF00";

            for (var i = 0; i < mesh.length; i++) {
              draw.fillRect(mesh[i][0], mesh[i][1], 2, 2);
            }
            

        }

        else

        {

            console.log(`no faces detected..`);

        }

        // loop to process the next frame

        await tf.nextFrame();

    }

}

Обратите внимание, что вы почти никогда не должны использовать while (1), вместо этого загляните в requestAnimationFrame (), который является способом создания циклов анимации. while (1) наверняка вызовет проблемы с производительностью, поскольку это бесконечное l oop и не ждет, пока браузер что-то сделает, поэтому просто не делайте этого. Я оставлю это вам в качестве упражнения по очистке кода.

...