我有一个图像,在一个场景中有一个校准目标(已知的几何形状)(假设一个简单的2" x 2"正方形躺在桌子上)。我想执行透视变换(使用warpPerspective()
),使所得到的图像是表的正交视图(好像相机轴与表法线平行)。计算单应性的标准程序是从一个一般平面到另一个不同的一般平面,其中在同一场景的两个图像中至少有4个对应(使用getPerspectiveTransform()
)。在这种情况下,我只有一个图像,简单地"构造"一个平面并将其对应于该平面上的任意位置是正确的吗?例如,在这种情况下,我只需在图像中检测到的4个角(A,B,C,D)和我选择的4个点(基本上只是定义像素->现实世界的比例)之间建立对应关系。例如,我可以选择A' = (0,0), B' = (20,20), C' = (0,20), D' =(20,0)来表示生成的图像中每英寸有10个像素。当然,我可以在这里选择任何比例,也可以选择正方形目标在输出中的任何位置(即A' = (100,100), B' = (120,120), C' = (100,120), D' =(120,100))。
这是"正确"的方法吗?有没有一种更好的方法来计算一个投影变换,它直接看一个平面,这个平面是由已知平面上的图像中的一组点定义的?
在这种情况下,我只有一个图像,是正确的事情去做简单地"组成"一个平面,并强制对应到某个任意位置在该平面上?
是的。
注意,getPerspectiveTransform
在目前的实现中恰好需要4个对应。它找到一个3x3的透视变换,它有8个自由度([3,3]元素是固定的1),所以它只需要4个非线性对应,任何这样的对应就足够了。findHomography
则采用RANSAC处理不确定性,能够分辨出哪些通信是可信的,哪些是异常值。如果你更喜欢线性最小二乘,你可以采用getPerspectiveTransform
来接受>=4对。
然而,如果你应用透视变换,将一些扭曲的正方形目标T
转换为完全正方形,这只会使与T
共面的平面也线平行。其他平面(例如,垂直于T
的平面)在转换后将不平行于线。
如果你想删除透视图,也就是说,将投影更改为正射影,你不能单独使用透视图变换来完成。你还需要知道场景中物体的深度,然后将其投影到平面上,而不需要透视。