【发布时间】:2020-11-21 12:55:35
【问题描述】:
我有一个 MxN RGB 图像,表示为 (M, N, 3) 数组 A。我还有另一个(3, 3) 矩阵B。我想将A 中的每个像素(一个3 向量)左乘以B 以获得(M, N, 3) 输出矩阵C,这样C[i][j] = B @ A[i][j]。在不循环A 中的像素的情况下如何做到这一点?
【问题讨论】:
标签: numpy
我有一个 MxN RGB 图像,表示为 (M, N, 3) 数组 A。我还有另一个(3, 3) 矩阵B。我想将A 中的每个像素(一个3 向量)左乘以B 以获得(M, N, 3) 输出矩阵C,这样C[i][j] = B @ A[i][j]。在不循环A 中的像素的情况下如何做到这一点?
【问题讨论】:
标签: numpy
你可以这样做
C = (B @ A[...,None]).reshape(A.shape)
【讨论】:
我认为您需要使用einsum 进行此类操作:
import numpy as np
shape = 10, 20, 3
A = np.random.random(np.product(shape)).reshape(shape)
B = np.random.random(9).reshape((3, 3))
print(np.einsum("ijk,lk", A, B).shape)
有关文档,请参阅 here。
【讨论】:
让我们重写:
C[i][j] = B @ A[i][j]
作为:
C[i,j,:] = B[:,:] @ A[i,j,:]
实际上我认为这是不对的,因为@ 将第一个中的最后一个与第二个与第二个的最后一个配对。 A 需要一个额外的“虚拟”维度。
其实更容易表达为:
np.einsum('ijk,lk->ijl',A,B)
np.einsum('ijk,kl->ijl',A,B.T)
所以
A @ B.T
(B @ A[:,:,:,None]).squeeze()
带数字:
In [33]: A = np.arange(24).reshape(2,4,3)
In [34]: B = np.arange(9).reshape(3,3)
In [35]: np.einsum('ijk,lk->ijl',A,B)
Out[35]:
array([[[ 5, 14, 23],
[ 14, 50, 86],
[ 23, 86, 149],
[ 32, 122, 212]],
[[ 41, 158, 275],
[ 50, 194, 338],
[ 59, 230, 401],
[ 68, 266, 464]]])
In [36]: A@B.T
Out[36]:
array([[[ 5, 14, 23],
[ 14, 50, 86],
[ 23, 86, 149],
[ 32, 122, 212]],
[[ 41, 158, 275],
[ 50, 194, 338],
[ 59, 230, 401],
[ 68, 266, 464]]])
In [37]: (B@A[...,None]).squeeze()
Out[37]:
array([[[ 5, 14, 23],
[ 14, 50, 86],
[ 23, 86, 149],
[ 32, 122, 212]],
[[ 41, 158, 275],
[ 50, 194, 338],
[ 59, 230, 401],
[ 68, 266, 464]]])
【讨论】: