arrays - 尽管网上有很多例子,但我无法在 python 中获得等效的 MATLAB repmat

标签 arrays matlab python-2.7 numpy tile

我正在尝试进行一些 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/

相关文章:

python - 通过 Python 读取 Outlook 事件

python - 命令 `python setup.py build_ext --inplace` 总是创建一个新目录

arrays - 循环 AWK 关联数组

mysql - 思考一种组织数据库的方法

java - 从动态 Java 类路径导入 Java 类的 Matlab 编译器 MCC 错误

matlab代码: Gaussian blurring in fourier domain

python 请求<响应[520]>

arrays - 使用 $addToSet Mongo 运算符添加多个值

c - 编译器如何在编译时不知道大小的情况下分配内存?

Python 互相关