2014-05-07 29 views
3

最近我在8x8塊圖像數據上做了很多處理。標準方法一直是使用嵌套的for-loops來提取塊,例如,numpy/scipy,在subarrays上循環

for y in xrange(0,height,8): 
    for x in xrange(0,width,8): 
     d = image_data[y:y+8,x:x+8] 
     # further processing on the 8x8-block 

我不禁懷疑是否有一種方法使用numpy的/ SciPy的,我可以用,而不是向量化該操作或其他方法嗎?某種類型的迭代器?

一個MWE :

#!/usr/bin/env python 

import sys 
import numpy as np 
from scipy.fftpack import dct, idct 
import scipy.misc 
import matplotlib.pyplot as plt 

def dctdemo(coeffs=1): 
    unzig = np.array([ 
     0, 1, 8, 16, 9, 2, 3, 10, 
     17, 24, 32, 25, 18, 11, 4, 5, 
     12, 19, 26, 33, 40, 48, 41, 34, 
     27, 20, 13, 6, 7, 14, 21, 28, 
     35, 42, 49, 56, 57, 50, 43, 36, 
     29, 22, 15, 23, 30, 37, 44, 51, 
     58, 59, 52, 45, 38, 31, 39, 46, 
     53, 60, 61, 54, 47, 55, 62, 63]) 

    lena = scipy.misc.lena() 
    width, height = lena.shape 

    # reconstructed 
    rec = np.zeros(lena.shape, dtype=np.int64) 

    # Can this part be vectorized? 
    for y in xrange(0,height,8): 
     for x in xrange(0,width,8): 
      d = lena[y:y+8,x:x+8].astype(np.float) 
      D = dct(dct(d.T, norm='ortho').T, norm='ortho').reshape(64) 
      Q = np.zeros(64, dtype=np.float) 
      Q[unzig[:coeffs]] = D[unzig[:coeffs]] 
      Q = Q.reshape([8,8]) 
      q = np.round(idct(idct(Q.T, norm='ortho').T, norm='ortho')) 
      rec[y:y+8,x:x+8] = q.astype(np.int64) 

    plt.imshow(rec, cmap='gray') 
    plt.show() 

if __name__ == '__main__': 
    try: 
     c = int(sys.argv[1]) 
    except ValueError: 
     sys.exit() 
    else: 
     if 1 <= int(sys.argv[1]) <= 64: 
      dctdemo(int(sys.argv[1])) 

腳註:

  1. 實際應用:https://github.com/figgis/dctdemo
+1

目前試圖擺弄它,讓我建議的功能與您的代碼一起工作... – YXD

回答

4

有一個函數view_as_windows這在Scikit圖片

不幸的是,我將不得不完成這個答案另一個時間,但你可以抓住表單中的窗口,你可以通到dct有:

from skimage.util import view_as_windows 
# your code... 
d = view_as_windows(lena.astype(np.float), (8, 8)).reshape(-1, 8, 8) 
dct(d, axis=0) 
+0

啊,scikit!穿過numpy&scipy的API,我找不到任何合適的東西(可能我沒有仔細考慮......) –

2

在scikit-learn特徵提取例程中有一個叫做extract_patches的函數。您需要指定和extraction_step。結果將作爲補丁顯示在圖像上,這可能會重疊。得到的陣列是4D,補丁的前2個索引,最後兩個索引補丁的像素。試試這個

from sklearn.feature_extraction.image import extract_patches 
patches = extract_patches(image_data, patch_size=(8, 8), extraction_step=(4, 4)) 

這給出了(8,8)大小的補丁重疊了一半。

請注意,直到現在,這使用沒有額外的內存,因爲它是使用跨步技巧實現的。你可以通過重塑來強制複製

patches = patches.reshape(-1, 8, 8) 

這基本上會產生一個補丁列表。

+0

Wow,'extract_patches'超好用,謝謝 – fish2000