我想通过不使用库函数来实现仿射变换。 我有一个名为“transformed”的图像,我想应用逆变换来获得“img_org”图像。现在,我正在使用我自己的基本GetBilinearPixel函数来设置强度值。但是,形象并没有改变好吧。这个是我想出来的。公司名称:
这是图像(“已转换.png“):
这是图像(“img_org.png“):
您可以在这里看到转换矩阵:
pts1 = np.float32( [[693,349] , [605,331] , [445,59]] )
pts2 = np.float32 ( [[1379,895] , [1213,970] ,[684,428]] )
Mat = cv2.getAffineTransform(pts2,pts1)
B=Mat
代码:
^{pr2}$我的逻辑错了吗?我知道我使用了非常低效的算法。 有什么我遗漏的见解吗? 或者你能给我其他的算法吗。在
(请求)。我不想用仿射函数。在
所以我对代码进行了矢量化,这个方法起作用了——我找不到你的实现的确切问题,但也许这会给你一些启示(加上速度快得多)。在
矢量化的设置是创建一个包含图像中每个点的线性(齐次)数组。我们需要一个看起来像
因此每个点
(xi, yi, 1)
都包含在内。那么变换就是用你的变换矩阵和这个数组的一个矩阵相乘。在为了简化问题(部分原因是您的图像命名约定让我感到困惑),我会说原始的起始图像是“destination”或
^{pr2}$dst
,因为我们想转换回“source”或src
图像。请记住,创建这种线性同质阵列可以如下所示:然后,要转换这些点,只需创建转换矩阵并乘法。我将取整变换后的像素位置,因为我将它们用作索引,而不必担心插值:
现在这个转换将把一些像素发送到负索引,如果我们用这些索引,它将环绕图像-可能不是我们想要做的。当然,在OpenCV实现中,它只是将这些像素完全切掉。但是我们可以移动所有变换后的像素,这样所有的位置都是正的,而且我们不会切断任何位置(当然,您可以在这方面做任何您想做的事情):
然后我们需要创建转换映射到的源映像
src
。我将用灰色背景创建它,这样我们就可以从dst
图像中看到黑色的范围。在现在我们要做的就是将目标图像中的一些对应像素放入源图像中。因为我没有切断任何像素,而且两个线性点阵列中的像素数目相同,所以我可以将变换后的像素指定为它们在原始图像中的颜色。在
当然,这不是在图像上插值。但是OpenCV中没有用于插值的内置函数(有后端C函数供其他方法使用,但不能在pythonafaik中访问)。但是,您有重要的部分-目标图像映射到的地方,以及原始图像,因此您可以使用任意数量的库来插值到网格上。或者你自己实现一个线性插值,因为它不太困难。当然,在此之前,您可能需要取消扭曲的像素位置。在
编辑:同样的方法也适用于
warpPerspective
,尽管你得到的矩阵乘法将得到一个三行(齐次)向量,并且你需要将前两行除以第三行,将它们重新设置为笛卡尔世界。其他的都是一样的。在相关问题 更多 >
编程相关推荐