首先,是我要实现的目标的直观示例:
(照片来源:https://unsplash.com/photos/pGcqw1ARGyg)
使用HTML5视频和画布,如何执行4点透视变换,以便仅在画布中渲染帧的“电视屏幕”部分?为什么my implementation没有显示正确的区域?
我正在尝试构建一个如下所示的网页:
我苦苦挣扎的部分是第4步。为了确保我只处理视频每一帧的图像的相关部分,重要的是我将图像“扭曲”为仅显示“电视屏幕”区域,而不显示整个网络摄像头图片。
做了一些阅读,我的理解是:
canvas
的解决方案,所以我不能简单地使用3D CSS转换(例如https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d)。这表明也许WebGL更适合我处理3D方面的事情。
考虑到这一点,我尝试了以下方法:
a)使用video
标签捕获网络摄像头
b)使用three.js,创建一个渲染到canvas
元素中的3D场景(以便我可以对生成的画布内容执行图像处理)
c)three.js场景包括:
-包含一个扁平网格,其中使用VideoTexture
在一侧显示视频。
-透视摄像头,最初放置时可以显示整个摄像头图像
d)允许用户单击四个角点来定义他们的电视在哪里,确定x / y坐标是什么并保存它们
e)计算透视变换,该变换将“拉伸”出图像,以便正确的区域“填满帧”。换句话说,将四个单击的“电视角”点拉伸到视口的四个角。我一直在使用这个库:https://github.com/jlouthan/perspective-transform来计算这个。f)我的想法是,如果将适当的变换应用于包含视频的网格,并且相机保持在固定位置,那么当以2D方式查看时,输出画布将包含所需的图像。
这是我目前在上面所做的尝试的链接。它显示了视频,并允许您单击四个角。如果单击原点(在中心)周围的点,这似乎可行,但是问题是,如果您选择图像中其他位置的区域,则会显示错误的区域。
https://bitbucket.org/mattwilson1024/perspective-transform/src/master/
我非常感谢您提供任何帮助,弄清为什么它无法按我的预期工作,或者对于是否有更好/更轻松的方法来实现我所需要的任何指示。
答案 0 :(得分:1)
原始实现的问题在于创建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);
This answer on the Math StackExchange对于解决此问题很有帮助。
为了将来任何人发现该问题的利益,我更新了原始问题,使其指向包含损坏代码的存档分支。可以找到有效的版本here。