2015-05-19 106 views
2

我有一個3D numpy陣列給出的圖像(寬度,高度和顏色爲尺寸)。現在我想提取給定形狀的所有可能的子圖像。例如,原始圖像的寬度和高度分別爲300和200像素,我想分別提取寬度和高度分別等於10和20像素的所有子圖像。此外,每個子圖像我想作爲一維數組(因爲我需要指定一個特定的像素排序)。如何有效地提取numpy中的子數組?

我解決以下列方式的問題:

for col0 in range(w_max - max_shift): 
    x3s_new = [x + col0 for x in x3s] 
    for row0 in range(h_max - max_shift): 

     vec_1 = [] 
     for col_shift, row_shift in px_inds: 
      col = col0 + col_shift 
      row = row0 + row_shift 
      vec_1 += [ia[row, col, 0], ia[row, col, 1], ia[row, col, 2]] 

     y3s_new = [y + row0 for y in y3s] 
     vec_2 = list(ia[y3s_new, x3s_new, z3s]) 

在上面的代碼中,我使過的「矩陣」表示圖像的列和行的循環。然後,將每個像素(由其列和行給出)視爲子圖像的左上角並提取子圖像。

vec_1vec_2是作爲1D陣列(列表)給出的期望的子圖像。它們是相同的,我只是想測試哪種方式更快。令人驚訝的是,生成vec_2vec_1需要更多時間。不過,根據我的問題,this answer預計會更快。那麼,爲什麼它不是更快?

最後,我還想知道是否有更快的替代方法來循環遍歷圖像矩陣的所有列和行。

總而言之,我的問題是:如何以更快的速度實現我所需要的?目前,我需要大約5分鐘來「處理」一個圖像,而且這對我的目的來說是不可接受的。

+2

你知道切片嗎? – cfh

+0

@cfh,no(some_symbols_to_make_it_acceptably_long)。 – Roman

回答

3

你應該使用Numpy切片。

給定3D numpy的陣列M,可以選擇它的一個子陣列,具有例如,

M_selection = M[i_min:i_max, j_min:j_max, k_min:k_max] 

或可選地,明確地限定切片,

sl_i = slice(i_min, i_max) 
sl_j = slice(j_min, j_max) 
sl_k = slice(k_min, k_max) 
M_selection = M[sl_i, sl_j, sl_k] 

其中(i_min, i_max),等等是子陣列的邊界。

查看高級Numpy索引的documentation瞭解更多詳情。

相關問題