2017-06-26 65 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()'而已 –