在 Python 中使用 OpenCV 重映射时的意外行为

Unexpected behaviour when using OpenCV remap in Python

我在 Opencv 中使用 cv2.remap 函数时遇到无法解释的行为。我做了一个函数,将每个像素的 y 坐标向上平移一个在每个 x 坐标上不同的数字。该数字是根据从 x=0 开始到 x=640 结束的基础曲线计算的(对于 360 x 640 图片)

大约一周前,我 post 回答了一个问题 但遇到了一个不同的问题 - 图像的顶部被裁剪了。这是回答,我明白问题是原始图像中的几个像素被映射到新图像中的相同位置,因此首先映射到顶部的像素被下部的其他像素覆盖。

但是我现在面临的问题有点不同,这就是为什么我 post 提出了一个新问题。在这种情况下,问题是因为我向上提升了所有 y 坐标,所以我希望图像的底部是空白的。这是通过以下代码实现的

original = cv2.imread('C:\Users\User\Desktop\alaskan-landscaps3.jpg')

        y_size,x_size=original.shape[:2]
        map_x = np.zeros(original.shape[:2], np.float32)
        map_y = np.zeros(original.shape[:2], np.float32)
for i in range(0, y_size):
    for j in range(0,x_size):
        map_y[i][j]=i+yvalues[j]
        map_x[i][j] = j

其中 yvalues[j] 是曲线在 x 坐标 j 处的 y 坐标。果然,当在 x=383 处打印 map_y 数组的前 10 行的 y 映射时,最小的数字是 199.102

for j in range(0, 360):
    print('At x=383,y=' + str(j) + ' mapping of y-coordinate is:' + str(map_y[j][383]))

At x=383,y=0 mapping of y-coordinate is:199.102
At x=383,y=1 mapping of y-coordinate is:200.102
At x=383,y=2 mapping of y-coordinate is:201.102
At x=383,y=3 mapping of y-coordinate is:202.102
At x=383,y=4 mapping of y-coordinate is:203.102
At x=383,y=5 mapping of y-coordinate is:204.102
At x=383,y=6 mapping of y-coordinate is:205.102

当我使用更复杂的变形函数时,相同的前 10 行得到以下结果 - 想法是垂直方向上的多个连续像素应映射到新图像中的相同像素

At x=383,y=0mapping is:199.102
At x=383,y=1mapping is:199.102
At x=383,y=2mapping is:199.102
At x=383,y=3mapping is:199.102
At x=383,y=4mapping is:199.102
At x=383,y=5mapping is:200.102
At x=383,y=6mapping is:200.102
At x=383,y=7mapping is:200.102
At x=383,y=8mapping is:200.102
At x=383,y=9mapping is:201.102
At x=383,y=10mapping is:201.102

不过,这一次,图像被完全填满,底部没有空白space。您可以在下面看到两张图片:

(像素化效果不是我想要的,但这是我要解决的问题:))。我已经检查了 map_y 数组中特定列的所有条目 x=383 并且所有值都> 199.102 所以看起来这与之前的情况不同,即没有更高的像素映射到下部的列。

所以我的问题是,导致这种剧烈变化的两种映射有何不同?我预计由于第二张图片的映射也是从高值开始的,所以底部也会有一个空白 space

很抱歉 post 但我已经尝试找出原因几天了,结果 none 更明智了。任何帮助将不胜感激。

我认为您误解了 remap() 的工作原理。 让我引用函数 initUndistortRectifyMap():

的 OpenCV 文档

"The function actually builds the maps for the inverse mapping algorithm that is used by remap(). That is, for each pixel (u, v) in the destination image, the function computes the corresponding coordinates in the source image."

所以你的台词

At x=383,y=0mapping is:199.102

其实就是映射图像中像素(383, 0)的值取自原图像中的像素(383, 199.102)

像素未映射,如果: a) map_x[i][j] or map_y[i][j] 的值为-1(short map类型为-16) 要么 b) 该值在源图像的边界之外。