2016-06-13 132 views
3

我已經做了一些搜索,但沒有找到完全相同的問題 - 我找到的解決方案不適用。如何將矩陣應用於圖像

我有一個圖像,由形狀的numpy陣列(l1,l2,3) 代表,其中l1,l2是整數,三是因爲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

這是一個3x3矩陣,依據變化的矩陣 – Gericault

+0

所以,做了發佈解決方案爲你工作? – Divakar

回答

0

您正在減少兩個輸入ImageP上的最後一個軸。所以,你可以使用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可能會更好。

運行測試

案例#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