我正在尝试进行一些 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 图像作为其 image 参数,该参数是一个 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,:),[尺寸(sm,1) 尺寸(sm,2)])
,
这是我的问题:
对此进行测试,尺寸为 800x479x3 的 OpenCV2 图像作为 image 参数传递,并且 (64, 48) (一个元组)作为 imSize 参数传递。 但是,在测试时,我收到以下 ValueError:
dmap = sm[:,:,:]-np.array([np.tile(sm[i,j,:], (len(sm[0]), len(sm[1]))) for k in xrange(len(sm[2]))])
ValueError: operands could not be broadcast together with shapes (48,64,3) (64,64,192)
所以看起来数组维度不匹配,numpy 有这个问题。但我的问题是什么呢?我该如何让它发挥作用?
最佳答案
这 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)
关于arrays - 尽管网上有很多例子,但我无法在 python 中获得等效的 MATLAB repmat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22184107/