Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用HTML5画布实现4点透视变换&;3.js?_Javascript_Typescript_Canvas_Three.js_Linear Algebra - Fatal编程技术网

Javascript 如何使用HTML5画布实现4点透视变换&;3.js?

Javascript 如何使用HTML5画布实现4点透视变换&;3.js?,javascript,typescript,canvas,three.js,linear-algebra,Javascript,Typescript,Canvas,Three.js,Linear Algebra,首先,我试图实现的一个可视化示例: (图片来源:) 简短的问题 使用HTML5视频和画布,如何执行4点透视变换,以便只渲染画布中帧的“电视屏幕”部分?为什么不显示正确的区域 关于我正在努力实现的目标的背景 我正在尝试构建一个网页,其工作原理如下: 用户将摄像头指向电视,使其位于画面的某个位置(但可能处于任何角度) 使用HTML5视频和画布,可以在网页上捕获和预览网络摄像头 用户可以定义(通过单击预览)电视屏幕的4个角的位置(4对x/y坐标) **视频被扭曲(使用某种透视变换),因此画布仅显示其

首先,我试图实现的一个可视化示例:

(图片来源:)

简短的问题 使用HTML5视频和画布,如何执行4点透视变换,以便只渲染画布中帧的“电视屏幕”部分?为什么不显示正确的区域

关于我正在努力实现的目标的背景 我正在尝试构建一个网页,其工作原理如下:

  • 用户将摄像头指向电视,使其位于画面的某个位置(但可能处于任何角度)
  • 使用HTML5视频和画布,可以在网页上捕获和预览网络摄像头
  • 用户可以定义(通过单击预览)电视屏幕的4个角的位置(4对x/y坐标)
  • **视频被扭曲(使用某种透视变换),因此画布仅显示其实际电视屏幕的部分图像(而不是整个网络摄像头视图)**
  • 然后对图像执行一些处理(例如,识别最突出的颜色)。这一部分超出了这个问题的范围,除了指出我希望能够在最后访问HTML5画布的内容/像素之外
  • 我正在努力的部分是第4步。为了确保我只处理视频每帧图像的相关部分,我必须“扭曲”图像,使其仅显示“电视屏幕”区域,而不是整个网络摄像头图片

    经过一点阅读,我的理解是:

    • 这需要某种透视变换,因为网络摄像头可以处于任何角度,而且我们没有处理平行线,所以需要进行三维变换,二维变换是不够的。这是因为2D变换(平移/旋转/缩放/倾斜)无法处理会聚边
    • HTML5画布是一个二维上下文,因此只能支持2D转换,而不能支持3D转换。因为我需要一个与
      画布
      一起工作的解决方案,所以我不能简单地使用3D CSS转换(例如)。这表明也许WebGL更适合我处理3D方面的问题
    到目前为止我所尝试的 考虑到这一点,我尝试了以下方法:

    a) 使用
    视频
    标签捕获网络摄像头

    b) 使用,创建一个3D场景,该场景被渲染为
    画布
    元素(以便我可以对生成的画布内容执行图像处理)

    c) three.js场景包括: -一种平面网格,其中包含使用
    视频纹理
    在一侧显示视频的网格。 -一个透视摄像头,最初定位为显示整个网络摄像头图像

    d) 允许用户单击四个角点以定义电视的位置,计算出x/y坐标并保存它们

    e) 计算透视变换,该变换将“拉伸”图像,以便正确的区域“填充帧”。换句话说,将四个单击的“电视角”点拉伸到视口的四个角。我一直在使用这个库:来计算这个

    f) 我的想法是,如果对包含视频的网格应用适当的变换,并且相机保持在固定位置,那么在2D中查看时,输出画布将包含所需的图像

    链接到我当前(已损坏)的实现 这里有一个链接到我目前在上面的尝试。它显示视频并允许您单击四个角。如果单击原点周围的点(在中心),它似乎可以工作,但问题是如果在图像的其他位置选择区域,它会显示错误的区域

    总结
    如果有人能帮助我找出为什么这不能如我所期望的那样工作,或者能为我提供一些关于是否有更好/更简单的方法来实现我所需要的东西的建议,我将不胜感激。

    原始实现的问题在于
    transformMatrix
    的创建方式

    我可以通过改变这一点来实现:

    transformMatrix.set(a1, a2, a3, 0, 
                        b1, b2, b3, 0, 
                        c1, c2, c3, 0, 
                        0,  0,  0,  1);
    
    为此:

    transformMatrix.set(a1, a2, 0, a3, 
                        b1, b2, 0, b3, 
                        0,  0,  0, 1, 
                        c1, c2, 0, c3);
    
    有助于解决这个问题

    为了方便将来发现这个问题的人,我更新了原始问题,使其指向包含损坏代码的归档分支。可以找到工作版本