为了账号安全,请及时绑定邮箱和手机立即绑定

如何将画布准确地堆叠在网络摄像头流的顶部?

如何将画布准确地堆叠在网络摄像头流的顶部?

达令说 2023-01-06 09:43:12

这是代码:


<!DOCTYPE html>

<html>

    <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>

        <meta charset="UTF-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1.0" />

        <title>Document</title>

        <script>

            async function get_facemesh() {

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


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


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


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


                while (1) {

                    const faces = await model.estimateFaces(stream);


                    if (faces.length != 0) {

                        canvas.width = canvas.width;


                        var mesh = faces[0].scaledMesh;

                        var widthAcross = mesh[454][0] - mesh[234][0];

                        var heightVertical = mesh[152][1] - mesh[10][1];


                        console.log(heightVertical);


                        draw.fillStyle = "red";


                        for (var i = 0; i < mesh.length; i++) {

                            draw.fillRect(mesh[i][0], mesh[i][1], 2, 2);

                        }

                    } else {

                        console.log(`No faces have been detected`);

                    }


                    await tf.nextFrame();

                }

            }

这是为那些喜欢的人提供的 codepen.io 链接:https ://codepen.io/mdsiam8/pen/gOrPayp 。


我尝试使用位置固定技巧,但它没有用,即使它们正好在彼此之上。感觉画布有点拉伸或者稍微向左变形。我试着摆弄这个但我找不到解决办法,所以如果你们中的任何人能帮助解决这个问题,我将不胜感激。顺便说一下,我知道在网络摄像头上偏移的小脸网是不正常的,因为我有另一个文件并使用了位置固定技巧,而且那个是完美的,所以我不确定为什么它不是这个也是如此。


查看完整描述

1 回答

?
侃侃尔雅

TA贡献1553条经验 获得超15个赞

的和属性设置<video>元素视觉内容的维度” ref,这意味着仅显示元素的显示方式。 您的面部检测器正在视频数据上处理视频的固有尺寸,即由媒体本身定义的尺寸,而不是由元素定义的尺寸,元素在显示视觉内容时会拉伸或缩小视觉内容。widthheight

另一方面,画布的widthheight属性确实设置了它的内在尺寸

所以这两种媒体的内在尺寸实际上是不同的,视频中的坐标与画布中的坐标不匹配。

要解决此问题,您只需将画布的和width分别设置为和,使其与视频内容的固有尺寸相匹配,然后通过 CSS调整其大小,使其与元素的显示尺寸相匹配。heightvideo.videoWidthvideo.videoHeight<video>

但是请注意,MediaStreams 可以在播放时更改其尺寸,因此您可能需要resize监听<video>.

链接到更新的代码笔,因为 StackSnippets 不允许 gUM。

最显着的变化:

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

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

if (navigator.mediaDevices.getUserMedia) {

  navigator.mediaDevices.getUserMedia({ video: true })

    .then( stream => {

    video.srcObject = stream;

    video.addEventListener( "resize", (evt) => {

      canvas.width = video.videoWidth;

      canvas.height = video.videoHeight;

    } );

    // don't poll, use events

    video.addEventListener( "loadedmetadata", (evt) => {

      get_facemesh();

    } );

  } );

}

video,

canvas {

  -webkit-transform: scaleX(-1);

  transform: scaleX(-1);

  position: fixed;

  margin: 0 auto;

  /* here set the same display dimensions */

  width: 600px;

  height: 450px;

  /* force same object fit too */

  object-fit: contain;

}

<div class="webcam">

  <video autoplay id="movie"></video>

  <canvas id="facemesh"> </canvas>

</div>


查看完整回答
反对 回复 2023-01-06
  • 1 回答
  • 0 关注
  • 10 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信