我正在尝试做一些numpy矩阵数学,因为我需要从MATLAB复制repmat函数。我知道网上有一千个例子,但我似乎无法让他们中的任何一个工作。
def getDMap(image, mapSize):
newSize = (float(mapSize[0]) / float(image.shape[1]), float(mapSize[1]) / float(image.shape[0]))
sm = cv.resize(image, (0,0), fx=newSize[0], fy=newSize[1])
for j in range(0, sm.shape[1]):
for i in range(0, sm.shape[0]):
dmap = sm[:,:,:]-np.array([np.tile(sm[j,i,:], (len(sm[0]), len(sm[1]))) for k in xrange(len(sm[2]))])
return dmap
函数getDMap(image,mapSize)需要一个OpenCV2 HSV图像作为其图像参数,这是一个具有3维维度的numpy数组:[:,:,:]
。它还期望一个带有2个元素的元组作为其 imSize 参数,当然要确保传递参数的函数考虑到在numpy数组中行和列交换(不:x,y,但:y,x)。
newSize 包含一个元组,其中包含用于将输入图像调整为特定比例的分数, sm 成为输入图像的调整大小版本。一切正常。
以下一行:
np.array([np.tile(sm[i,j,:], (len(sm[0]), len(sm[1]))) for k in xrange(len(sm[2]))])
,
应该等效于MATLAB表达式:
repmat(sm(j,i,:),[size(sm,1) size(sm,2)])
,
测试一下,尺寸 800x479x3 的OpenCV2图像作为图像参数传递,(64,48)(一个元组)作为 imSize 参数传递。 但是在测试时,我得到以下 ValueError:
dmap = sm [:,:,]: - np.array([np.tile(sm [i,j,:],(len(sm [0]), len(sm [1])))for x in xrange(len(sm [2]))])
ValueError:无法与操作数一起广播 形状(48,64,3)(64,64,192)
所以似乎数组维度不匹配,numpy有问题。但我的问题是什么?我该如何使用呢?
答案 0 :(得分:2)
len(sm[0])
和len(sm[1])
不是sm
的第一维和第二维的大小。它们是sm
的第一行和第二行的长度,并且都应返回相同的值。您可能希望将它们替换为sm.shape[0]
和sm.shape[1]
,它们等同于您的Matlab代码,但我不确定它是否会像您期望的那样工作。
答案 1 :(得分:2)
这两个计算匹配:
octave:26> sm=reshape(1:12,2,2,3)
octave:27> x=repmat(sm(1,2,:),[size(sm,1) size(sm,2)])
octave:28> x(:,:,2)
7 7
7 7
In [45]: sm=np.arange(1,13).reshape(2,2,3,order='F')
In [46]: x=np.tile(sm[0,1,:],[sm.shape[0],sm.shape[1],1])
In [47]: x[:,:,1]
Out[47]:
array([[7, 7],
[7, 7]])
这运行:
sm[:,:,:]-np.array([np.tile(sm[0,1,:], (2,2,1)) for k in xrange(3)])
但它产生一个(3,2,2,3)数组,在第一维上复制。我不认为你想要k
循环。
意图是什么?
for i in ...:
for j in ...:
data = ...
您只会获得上次迭代的结果。你想要data += ...
吗?如果是这样,这可能有效(对于(N,M,K)形状sm
)
np.sum(np.array([sm-np.tile(sm[i,j,:], (N,M,1)) for i in xrange(N) for j in xrange(M)]),axis=0)
z = np.array([np.tile(sm[i,j,:], (N,M,1)) for i in xrange(N) for j in xrange(M)]),axis=0)
np.sum(sm - z, axis=0) # let numpy broadcast sm
实际上我甚至不需要瓷砖。让广播做这项工作:
np.sum(np.array([sm-sm[i,j,:] for i in xrange(N) for j in xrange(M)]),axis=0)
我可以用repeat
摆脱循环。
sm1 = sm.reshape(N*M,L) # combine 1st 2 dim to simplify repeat
z1 = np.repeat(sm1, N*M, axis=0).reshape(N*M,N*M,L)
x1 = np.sum(sm1 - z1, axis=0).reshape(N,M,L)
我也可以将广播应用到最后一个案例
x4 = np.sum(sm1-sm1[:,None,:], 0).reshape(N,M,L)
# = np.sum(sm1[None,:,:]-sm1[:,None,:], 0).reshape(N,M,L)
使用sm
我必须扩展(和求和)2维:
x5 = np.sum(np.sum(sm[None,:,None,:,:]-sm[:,None,:,None,:],0),1)