2017-06-26 61 views
0

我想創建一個高斯模糊矩陣。我從http://www.labri.fr/perso/nrougier/teaching/numpy/numpy.html向量化與numpy

修改代碼dev_data具有784個像素特徵的行,並且我希望模糊像素周圍的鄰居以及像素本身。當我們沿着外邊緣(第1行,-1,第1列,第-1行)時,丟棄任何超出邊界的鄰居。我不太清楚如何做這個丟棄。

代碼:

# Initialize a new feature array with the same shape as the original data. 
blurred_dev_data = np.zeros(dev_data.shape) 

#we will reshape the 784 feature-long rows into 28x28 matrices 
for i in range(dev_data.shape[0]): 
    reshaped_dev_data = np.reshape(dev_data[i], (28,28)) 
    #the purpose of the reshape is to use the average of the 8 pixels + the pixel itself to blur 
    for idx, pixel in enumerate(reshaped_dev_data): 
     pixel = np.mean(reshaped_dev_data[idx-1:idx-1,idx-1:idx-1] + reshaped_dev_data[idx-1:idx-1,idx:idx] + reshaped_dev_data[idx-1:idx-1,idx+1:] + 
      reshaped_dev_data[idx:idx,idx-1:idx-1] + reshaped_dev_data[idx:idx,idx:idx] + reshaped_dev_data[idx:idx,idx+1:] + 
      reshaped_dev_data[idx+1: ,idx-1:idx-1] + reshaped_dev_data[idx+1: ,idx:idx] + reshaped_dev_data[idx+1: ,idx+1:]) 
    blurred_dev_data[i,:] = reshaped_dev_data.ravel() 

我得到一個錯誤與指數:

ValueError: operands could not be broadcast together with shapes (0,0) (0,27) 

這不是一個indexerror,所以我不太清楚我在做什麼錯在這裏/如何修理它。

+0

編輯'reshaped_dev_data [idx-1:idx-1,idx-1:idx-1]'到'reshaped_dev_data [idx-1,idx-1]'等等。 – Divakar

+0

謝謝。現在我得到了我期待的界限錯誤。你知道一個忽略出界指數的好方法嗎? –

+0

我建議使用高斯模糊濾鏡,而不是 - https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.ndimage.filters.gaussian_filter.html – Divakar

回答

1

試試這個:

pixel = np.mean(reshaped_dev_data[idx-1:idx+1, idx-1:idx+1]) 

此外,瞭解slicing


所以我還看着你的代碼,你做錯了幾件事情:

  • 這不是一個高斯內核。
  • 重複計算reshaped_dev_data多次循環。
  • 循環錯誤的東西。
  • 試圖在第9行這變異pixel是不好的,因爲:
    • 你遍歷對象的突變是普遍不好
    • 這不會反正變異! pixel就像是一個「價值」持有人。改變它不會改變你正在循環的數組。
  • 不寫矢量化的代碼!

下面是做這件事的天真,非矢量化方式:

def conv(arr, i, j): 
    return np.mean(arr[i-1:i+1, j-1:j+1]) 

blurred_dev_data = np.zeros_like(dev_data) 
reshaped_dev_data = dev_data.reshape(28, 28) 

for i, row in enumerate(reshaped_dev_data): 
    for j, pixel in enumerate(row): 
     blurred_dev_data[i, j] = conv(reshaped_dev_data, i, j) 

請注意,我們正在做的卷積。所以我們可以簡單地使用內置庫來對平均內核執行卷積。


關於你的評論,

def conv(arr, i, j): 
    # Ensure the boundaries are not exceeded 
    a = max(i-1, 0) 
    b = min(i+1, 28) 
    c = min(j-1, 0) 
    d = max(i+1, 28) 

    return np.mean(arr[a:b, c:d]) 

blurred_dev_data = np.zeros_like(dev_data) 

for n, data in enumerate(dev_data): 
    reshaped = data.reshape(28, 28) 
    blurred = np.zeros_like(reshaped) 

    for i, row in enumerate(reshaped): 
     for j, pixel in enumerate(row): 
      blurred[i, j] = conv(reshaped, i, j) 

    blurred_dev_data[n] = blurred.ravel() 

通知我修改conv因爲我忘了,以確保邊界不是超標。

注:它是非常非常更快地使用現有的庫如SciPy的或OpenCV的執行2D卷積,或在這種情況下,平均值平均濾波器。

+0

謝謝你的幫助。你能告訴我如何使用.ravel()來捲起blur_dev_data中的行嗎?我把你的第5行改爲'for i in range(dev_data.shape [0]): reshaped_dev_data = np.reshape(dev_data [i],(28,28))'因爲我需要重新塑造dev_data的每一行。 –

+0

@FredericBastiat你的意思是把一個28x28矩陣變成764長度的矢量嗎?那只是'vector = matrix.ravel()'而已 –