我已经进行了一些搜索,但没有找到完全相同的问题 - 我找到的解决方案也没有适应性。
我有一个图像,由一个形状为(l1,l2,3)
的numpy数组表示
其中l1,l2是整数,3是因为RGB。
由于原因,我想改变基础,这意味着将矩阵P应用于所有RGB矢量。请注意,P
的形状为(3,3)
。
我写过:
def change_base(Image,P):
Image_copie=np.zeros(Image.shape)
for i in range(Image_copie.shape[0]):
for j in range(Image_copie.shape[1]):
Image_copie[i,j]=np.dot(P,Image[i,j])
return Image_copie
显然,它很有效,但它很丑陋且非常慢。
你们有没有解决方案,也许使用numpy?我没有使用opencv ..!
谢谢!
答案 0 :(得分:0)
您正在减少两个输入Image
和P
上的最后一个轴。因此,您可以使用np.tensordot
,就像这样 -
np.tensordot(Image,P,axes=(-1,-1))
这也可以表示为np.dot
,在它之前和之后进行一些重塑,就像这样 -
Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
还可以使用np.einsum
进行此类缩减操作,如此 -
np.einsum('ijk,lk->ijl',Image,P)
对于性能而言,作为单独的还原操作,没有轴对齐要求,dot-based
解决方案对于大型阵列会更快,但对于小到适当大小的阵列,einsum
可能会更好。< / p>
运行时测试
案例#1:
In [46]: # Inputs
...: Image = np.random.randint(0,255,(256,256,3))
...: P = np.random.randint(0,255,(3,3))
...:
In [47]: %timeit change_base(Image,P)
...: %timeit np.tensordot(Image,P,axes=(-1,-1))
...: %timeit Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
...: %timeit np.einsum('ijk,lk->ijl',Image,P)
...:
1 loops, best of 3: 206 ms per loop
100 loops, best of 3: 3.28 ms per loop
100 loops, best of 3: 3.22 ms per loop
100 loops, best of 3: 3.06 ms per loop
案例#2:
In [48]: # Inputs
...: Image = np.random.randint(0,255,(512,512,3))
...: P = np.random.randint(0,255,(3,3))
...:
In [49]: %timeit change_base(Image,P)
...: %timeit np.tensordot(Image,P,axes=(-1,-1))
...: %timeit Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
...: %timeit np.einsum('ijk,lk->ijl',Image,P)
...:
1 loops, best of 3: 845 ms per loop
100 loops, best of 3: 12.8 ms per loop
100 loops, best of 3: 12.7 ms per loop
100 loops, best of 3: 13.4 ms per loop