最近我也遇到了一个主题,即 skimage 几何变换和 opencv 中的等价变换之间的区别。我的目标是替换下面示例中的skimage.transform.warp
函数。仅从基本外观来看,它们的工作方式相似,默认情况下borderMode
或borderValue
也是相同的,但我没有收到相同的结果。我错过了什么?
import numpy as np
import skimage.transform
import cv2
img = np.random.rand(16,16)
angle = np.deg2rad(45)
cos_a, sin_a = np.cos(angle), np.sin(angle)
R = np.array([[cos_a, sin_a, -11 * (cos_a + sin_a - 1)],
[-sin_a, cos_a, -11 * (cos_a - sin_a - 1)],
[0, 0, 1]])
skimage_rotated = skimage.transform.warp(img, R, clip=False)
cv2_rotated = cv2.warpPerspective(img, R, dsize=skimage_rotated.shape)
print(np.count_nonzero(np.where(np.abs(skimage_rotated - cv2_rotated) > 1e-1)))) #356
plt.imshow(np.abs(skimage_rotated - cv2_rotated))
plt.show()
1条答案
按热度按时间dddzy1tm1#
问题是
skimage.transform.warp
执行向后转换,而cv2.warpPerspective
执行向前转换。将
cv2.WARP_INVERSE_MAP
标志传递给cv2.warpPerspective
解决了这个问题。(我们也可以发明变换矩阵):skimage.transform.warp文档:
skimage.transform.warp(image,inverse_map,map_args=None,...
inverse_maptransformation对象,可调用cr = f(cr,**kwargs)或ndarray
逆坐标Map,将输出图像中的坐标转换为输入图像中对应的坐标。
cv2.warpPerspective文档:
函数warpPerspective转换源图像...
当标志WARP_INVERSE_MAP被设置时。否则,转换首先使用invert进行inverted,然后将M放入上述公式中。
代码示例:
np.abs(skimage_rotated - cv2_rotated)
: