尝试将横向图像旋转为纵向时,应用旋转后,我无法在图像上绘制。
img1 = cv2.imread('a.jpg')
cv2.circle(img1, tuple([10,10]),radius = 3, color = (255,0,0))
工作正常。
然后我尝试:
img2 = np.rot90(img1,3)
cv2.circle(img2, tuple([10,10]),radius = 3, color = (255,0,0))
我收到错误:
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
查看type(img2)
和img2.dtype
,它似乎与img1相同。
尺寸看起来也很好(前两个尺寸翻转,第三个尺寸保持“3”)
img2 = np.rot90(img1,3)
img3 = img2.copy()
cv2.circle(img3, tuple([10,10]),radius = 3, color = (255,0,0))
答案 0 :(得分:3)
我有同样的问题,从来没有深究过它。我使用的解决方法是使用OpenCV进行图像旋转/翻转,例如:
# flip image vertically
img = cv2.flip(img, 0)
# flip image horizontally
img = cv2.flip(img, 1)
# transpose image
img = cv2.transpose(img)
请注意,旋转相当于进行转置和翻转。
答案 1 :(得分:0)
np.rot90
本身并没有完全破坏图像。这背后的原因是因为 OpenCV 无法处理 numpy 数组的“视图”。 np.rot90
以及其他几个 numpy 操作实际上并不修改底层数组,而是将修改后的“视图”返回给数组。这通常会在 OpenCV 操作中引发以下错误:
Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
Expected Ptr<cv::UMat> for argument 'img'
像 np.rot90(img1)
、np.fliplr(img1)
、np.flipud(img1)
、np.transpose(img1, (1, 0, 2))
等操作都只是返回视图,并且都会抛出上述相同的错误。
添加 .copy()
可以解决错误的原因是,当在视图上调用 .copy()
时,它会作为与原始数组不同的新数组存储在内存中。您实际上可以非常简单地验证这一点:
import numpy as np
img = np.random.choice(256, (50, 100, 3)).astype(np.uint8)
img_r = np.rot90(img)
print(img_r == img)
# False
print(np.shares_memory(img, img_r))
# True
img_r = img_r.copy()
print(np.shares_memory(img, img_r))
# False
如您所见,即使 img_r == img
显示 False
,它们仍然共享相同的内存——因为 img_r
是 img
的视图。但是在调用 .copy()
之后,视图 img_r
变成了它自己的数组,不再与原来的 img
共享内存。