Python 转置numpy矩阵会导致cv';s绘制函数以抛出错误
在转置numpy矩阵时,我在使用cv显示它们时遇到了一些问题 考虑以下代码Python 转置numpy矩阵会导致cv';s绘制函数以抛出错误,python,opencv,numpy,Python,Opencv,Numpy,在转置numpy矩阵时,我在使用cv显示它们时遇到了一些问题 考虑以下代码 import cv2, numpy as np ... ones = np.ones((100,100)) onesT = np.copy(ones.T) onesCT = np.copy(ones.T, order='C') cv2.circle(ones, (50,50), 3, (0), thickness=-1) cv2.circle(onesCT, (50,50), 3, (0), thickness=-1)
import cv2, numpy as np
...
ones = np.ones((100,100))
onesT = np.copy(ones.T)
onesCT = np.copy(ones.T, order='C')
cv2.circle(ones, (50,50), 3, (0), thickness=-1)
cv2.circle(onesCT, (50,50), 3, (0), thickness=-1)
cv2.circle(onesT, (50,50), 3, (0), thickness=-1)
前两个“cv2.circle”调用work,但第三个给了我以下错误:
102 cv2.circle(ones, (50,50), 3, (0), thickness=-1)
103 cv2.circle(onesCT, (50,50), 3, (0), thickness=-1)
--> 104 cv2.circle(onesT, (50,50), 3, (0), thickness=-1)
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
为什么转置矩阵会发生这种情况,但如果我改变了内存的复制顺序,就不会发生这种情况?对我来说,所有这些矩阵都是完全相同的。在一个抽象层次上,所有这些矩阵都是相同的。但在较低的级别,其中两个使用数组的C约定()存储数据,另一个(
onesT
)使用Fortran约定(列主顺序)。显然cv2.circle
需要一个C-连续数组
您可以使用flags
属性检查顺序。请注意,onesT
的F_continuous
标志为True:
In [24]: ones.flags
Out[24]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
In [25]: onesT.flags
Out[25]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
In [26]: onesCT.flags
Out[26]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
检查订单信息的简明方法是:
onesT
使用Fortran顺序,因为二维数组的转置是在numpy中实现的,只需交换每个维度的“步幅”,而不实际复制内存中的值数组
比如说,
In [28]: x = np.array([[1, 2, 3], [4, 5, 6]])
In [29]: np.isfortran(x)
Out[29]: False
In [30]: np.isfortran(x.T)
Out[30]: True
(这使得转置操作非常有效。)
您复制了转置数组以创建
onesT
,但是如果查看的docstring,您将看到order
参数的默认值是'K'
,这意味着“尽可能地匹配a的布局”。特别是,在这种情况下,它保留了Fortran顺序<另一方面,code>onesCT是一个C-连续数组,因为您明确告诉np.copy
使用C约定订购副本。非常感谢您的详细解释!
In [28]: x = np.array([[1, 2, 3], [4, 5, 6]])
In [29]: np.isfortran(x)
Out[29]: False
In [30]: np.isfortran(x.T)
Out[30]: True