gpt4 book ai didi

python - 如何使用 OpenCV 的重映射功能?

转载 作者:太空狗 更新时间:2023-10-29 20:33:09 24 4
gpt4 key购买 nike

这是 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 范围内的插值。

我已经阅读了所有文档。它和 SO 上的每个人都声明你输入一个起点数组( map ),一个终点 map ,然后 remap() 会将 img 中的所有值放入它们的新位置,插入任何空白空间。我正在这样做,但它不起作用。为什么?大多数示例适用于 C++。它在python中坏了吗?

最佳答案

这只是对文档的一个简单误解,我不怪你——我也花了一些时间才理解它。文档很清楚,但是这个函数可能不会按照你期望的方式工作;事实上,它的工作方向与我最初预期的相反

remap() 不会做的是获取源图像的​​坐标、转换点,然后进行插值。 remap() 做的是,对于目标图像中的每个像素,在源图像中查找它来自哪里,然后分配一个插值。它需要以这种方式工作,因为为了进行插值,它需要在每个像素处查看源图像周围的值。让我扩展一下(可能会重复一下,但不要误会)。

来自remap() docs :

map1 – The first map of either (x,y) points or just x values having the type CV_16SC2 , CV_32FC1 , or CV_32FC2 . See convertMaps() for details on converting a floating point representation to fixed-point for speed.

map2 – The second map of y values having the type CV_16UC1 , CV_32FC1 , or none (empty map if map1 is (x,y) points), respectively.

map1 上的“the first map of...”的措辞可能令人困惑。请记住,这些是您的图像从 映射的严格坐标...这些点是 src at map_x (x, y), map_y(x, y) 然后放入dst at x, y。而且它们应该与您要将它们变形为 的图像形状相同。请注意文档中显示的等式:

dst(x,y) =  src(map_x(x,y),map_y(x,y))

此处 map_x(x, y)x, y 给出的行和列中查找 map_x。然后在这些像素处评估图像值。它在 src 中查找 x, y 的映射坐标,然后将该值赋给 dst x, y。如果你盯着它看的时间足够长,它就会开始变得有意义。在新目标图像中的像素 (0, 0) 处,我查看 map_xmap_y,它们告诉我相应像素在源图像,然后我可以通过查看源图像中的附近值在目标图像中的 (0, 0) 处分配一个插值。这是 remap() 以这种方式工作的根本原因;它需要知道一个像素来自哪里才能让相邻像素进行插值。

小的,做作的例子

img = np.uint8(np.random.rand(8, 8)*255)
#array([[230, 45, 153, 233, 172, 153, 46, 29],
# [172, 209, 186, 30, 197, 30, 251, 200],
# [175, 253, 207, 71, 252, 60, 155, 124],
# [114, 154, 121, 153, 159, 224, 146, 61],
# [ 6, 251, 253, 123, 200, 230, 36, 85],
# [ 10, 215, 38, 5, 119, 87, 8, 249],
# [ 2, 2, 242, 119, 114, 98, 182, 219],
# [168, 91, 224, 73, 159, 55, 254, 214]], dtype=uint8)

map_y = np.array([[0, 1], [2, 3]], dtype=np.float32)
map_x = np.array([[5, 6], [7, 10]], dtype=np.float32)
mapped_img = cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR)
#array([[153, 251],
# [124, 0]], dtype=uint8)

那么这里发生了什么?在这种情况下,最容易检查矩阵:

map_y
=====
0 1
2 3

map_x
=====
5 6
7 10

因此 (0, 0) 处的目标图像与 map_y(0, 0)、map_x(0, 0) = 0, 5 处的源图像和源图像具有相同的值在第 0 行和第 5 列是 153。请注意,在目标图像中 mapped_img[0, 0] = 153。因为我的 map 坐标是精确的整数,所以这里没有插值。我还包含了一个越界索引(map_x[1, 1] = 10,它大于图像宽度),并注意到它刚刚被分配了值 0 越界时。

完整用例示例

这是一个完整的代码示例,使用地面实况单应性,手动扭曲像素位置,然后使用 remap() 从转换后的点映射图像。请注意,我的单应变换 true_dst src。因此,我制作了一组我想要的点,然后通过单应性变换计算这些点在源图像中的位置。然后使用 remap() 在源图像中查找这些点,并将它们映射到目标图像中。

import numpy as np
import cv2

# read images
true_dst = cv2.imread("img1.png")
src = cv2.imread("img2.png")

# ground truth homography from true_dst to src
H = np.array([
[8.7976964e-01, 3.1245438e-01, -3.9430589e+01],
[-1.8389418e-01, 9.3847198e-01, 1.5315784e+02],
[1.9641425e-04, -1.6015275e-05, 1.0000000e+00]])

# create indices of the destination image and linearize them
h, w = true_dst.shape[:2]
indy, indx = np.indices((h, w), dtype=np.float32)
lin_homg_ind = np.array([indx.ravel(), indy.ravel(), np.ones_like(indx).ravel()])

# warp the coordinates of src to those of true_dst
map_ind = H.dot(lin_homg_ind)
map_x, map_y = map_ind[:-1]/map_ind[-1] # ensure homogeneity
map_x = map_x.reshape(h, w).astype(np.float32)
map_y = map_y.reshape(h, w).astype(np.float32)

# remap!
dst = cv2.remap(src, map_x, map_y, cv2.INTER_LINEAR)
blended = cv2.addWeighted(true_dst, 0.5, dst, 0.5, 0)
cv2.imshow('blended.png', blended)
cv2.waitKey()

Remap for warping

来自 Visual Geometry Group at Oxford 的图像和地面真实单应性.

关于python - 如何使用 OpenCV 的重映射功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46520123/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com