下面是remap()最简单的测试用例:
import cv2
import numpy as np
inimg = np.arange(2*2).reshape(2,2).astype(np.float32)
inmap = np.array([[0,0],[0,1],[1,0],[1,1]]).astype(np.float32)
outmap = np.array([[10,10],[10,20],[20,10],[20,20]]).astype(np.float32)
outimg = cv2.remap(inimg,inmap,outmap,cv2.INTER_LINEAR)
print "inimg:",inimg
print "inmap:",inmap
print "outmap:",outmap
print "outimg:", outimg
结果如下:
inimg: [[ 0. 1.]
[ 2. 3.]]
inmap: [[ 0. 0.]
[ 0. 1.]
[ 1. 0.]
[ 1. 1.]]
outmap: [[ 10. 10.]
[ 10. 20.]
[ 20. 10.]
[ 20. 20.]]
outimg: [[ 0. 0.]
[ 0. 0.]
[ 0. 0.]
[ 0. 0.]]
如您所见,outimg产生0,0,而且它的形状甚至不正确。我希望是20x20或10x10图像,插值范围为0到3。
我看过所有的文件。它和everyone on SO状态下,您输入一个数组(一个映射)开始点,一个映射结束点,然后remap()将把img中的所有值放入它们的新位置,插入任何空格。我这么做了,但没用。为什么?大多数例子是C++。是Python破的吗?
这只是对文件的一个简单的误解,我不怪你——我也花了几次摸索才明白。文档很清楚,但是这个函数可能没有按您预期的方式工作;事实上,它在与我最初预期相反的方向工作。
remap()
没有做的是获取源图像的坐标,变换点,然后插值。remap()
所做的是,对于目的地图像中的每个像素,查找它来自源图像中的位置,然后分配一个插值值。它需要这样工作,因为为了插值,它需要查看每个像素处源图像周围的值。让我扩展一下(可能会重复一下,但不要误会)。从^{} docs :
这里关于
map1
的“Thefirstmap of…”的措辞有些误导。记住,这些是图像从映射的坐标……这些点从map_x(x, y), map_y(x, y)
的src
映射,然后放在x, y
的dst
中。它们应该和你想把它们扭曲成的图像形状一样。请注意文档中显示的公式:这里
map_x(x, y)
在x, y
给定的行和列上查找map_x
。然后在这些点对图像进行求值。它查找src
中x, y
的映射坐标,然后将该值赋给dst
中的x, y
。如果你盯着它看够久,它就开始有意义了。在新目标图像中的像素(0, 0)
处,我查看map_x
和map_y
,它们告诉我源图像中相应像素的位置,然后通过查看源图像中的接近值,可以在目标图像中的(0, 0)
处分配插值。这就是remap()
以这种方式工作的基本原因;它需要知道像素从哪里来,以便它可以看到要插值的相邻像素。做作的小例子
那这里发生了什么?记住,这些是
img
的索引,将映射到它们所在的行和列。在这种情况下,最容易检查矩阵:因此(0,0)处的目标图像与
map_y(0, 0), map_x(0, 0) = 0, 5
处的源图像具有相同的值,第0行和第5列处的源图像是153。请注意,在目标图像中mapped_img[0, 0] = 153
。这里没有插值,因为我的地图坐标是精确的整数。此外,我还包含了一个越界索引(map_x[1, 1] = 10
,它大于图像宽度),注意,当它越界时,它只是被赋值为0
。完整用例示例
下面是一个完整的代码示例,使用地面真值单应,手动扭曲像素位置,然后使用
remap()
从转换点映射图像。注意,这里我的单应式将true_dst
转换为src
。因此,我建立了一个任意多个点的集合,然后通过用单应变换计算这些点在源图像中的位置。然后使用remap()
查找源图像中的这些点,并将它们映射到目标图像中。来自Visual Geometry Group at Oxford的图像和基本真实同音字。
相关问题 更多 >
编程相关推荐