2016-06-09 82 views
2

我正在生成一些基本的高斯濾波演示,但得到奇特的輸出圖,因爲它們不是線性模糊的。下面的代碼導入任何圖像,然後應用std(sigma)值爲1,大小爲5的高斯濾波器。高斯圖像過濾圖低stdev。值

我認爲這可能是一個有限vs無限濾波器陣列假設問題,但不確定。 conv2函數不是我自己的,而是Matlabs conv2函數的一個類似函數,我在這裏找到了。

import numpy as np 
from PIL import Image 
import matplotlib.pyplot as plt 
from scipy.ndimage.filters import convolve 


def conv2(x,y): 
    """ 
    This function the 2D convolution of two 2D input array x and y. 

    Parameters 
    ---------- 
    x : ndarray 
    y : ndarray  

    Returns 
    ---------- 
    z : convolved image output 

    Usage: 
    z = conv2(x,y,mode='same') 

    """ 

    # Add singleton dimensions 
    if (len(x.shape) < len(y.shape)): 
     dim = x.shape 
     for i in range(len(x.shape),len(y.shape)): 
      dim = (1,) + dim 
     x = x.reshape(dim) 
    elif (len(y.shape) < len(x.shape)): 
     dim = y.shape 
     for i in range(len(y.shape),len(x.shape)): 
      dim = (1,) + dim 
     y = y.reshape(dim) 

    origin =() 

    # Apparently, the origin must be set in a special way to reproduce 
    # the results of scipy.signal.convolve and Matlab 
    for i in range(len(x.shape)): 
     if ((x.shape[i] - y.shape[i]) % 2 == 0 and 
      x.shape[i] > 1 and 
      y.shape[i] > 1): 
      origin = origin + (-1,) 
     else: 
      origin = origin + (0,) 

    z = convolve(x,y, mode='constant', origin=origin) 

    return z 


# Question 1 - Guassian Blur 
def Gaussian_filter(gamma, N): 
    """ 
    Create the Gaussian filters 
    """ 
    Amp = 1/(2*np.pi*gamma**2) 
    x = np.arange(-N,N,0.5) 
    y = np.arange(-N,N,0.5) 
    [x,y] = np.meshgrid(x,y) 
    g = Amp * np.exp(-(x**2 + y **2)/(2*gamma**2)) 
    return g 

im = Image.open("/home/will/Downloads/lenaTest3.jpg") 
arr = np.array(im) 

sigma=1 
N=5 
gaus = Gaussian_filter(sigma,5) 

plt.figure(1) 
plt.subplot(1,4,1) 
plt.imshow(arr,cmap='gray') 
plt.subplot(1,4,2) 
plt.imshow(gaus,cmap='gray') 
plt.subplot(1,4,3) 
plt.imshow(conv2(arr,gaus),cmap='gray',vmin=0,vmax=255) 
plt.subplot(1,4,4) 
plt.imshow(arr-conv2(arr,gaus),cmap='gray',vmin=0,vmax=255) 

Example of output plots

您可以在右邊兩個圖像看到高斯模糊都是不正規的。注意:對於更高的stdev(西格馬)值,例如10.

回答

2

看起來像一個8位integer overflow的問題。您可以處理浮動圖像,並避免這樣的問題:arr = np.array(im, dtype=np.float32)

順便說一句,爲什麼不使用scipy.signal.convolve2d? 轉換一些MATLAB代碼更安全(我看到它給出了不同的結果)。

你完整的代碼應該是這樣的:

import numpy as np 
from PIL import Image 
import matplotlib.pyplot as plt 
from scipy.signal import convolve2d 

def Gaussian_filter(gamma, N): 
    Amp = 1/(2*np.pi*gamma**2) 
    x = np.arange(-N,N,0.5) 
    y = np.arange(-N,N,0.5) 
    [x,y] = np.meshgrid(x,y) 
    g = Amp * np.exp(-(x**2 + y **2)/(2*gamma**2)) 
    return g 

if __name__ == "__main__": 
    im = Image.open(r"C:\Users\eladj\Desktop\lena.jpg") 
    arr = np.array(im, dtype=np.float32) 

    sigma = 1 
    N = 5 

    gaus = Gaussian_filter(sigma,5) 
    im_blurred = convolve2d(arr, gaus, mode='same') 
    im_DoG = arr - im_blurred 

    plt.figure(1) 
    plt.subplot(1,4,1) 
    plt.imshow(arr, cmap='gray') 
    plt.colorbar(fraction=0.046) 
    plt.xticks([]), plt.yticks([]) 
    plt.subplot(1,4,2) 
    plt.imshow(gaus, cmap='gray') 
    plt.colorbar(fraction=0.046) 
    plt.xticks([]), plt.yticks([]) 
    plt.subplot(1,4,3) 
    plt.imshow(im_blurred, cmap='gray') 
    plt.colorbar(fraction=0.046) 
    plt.xticks([]), plt.yticks([]) 
    plt.subplot(1,4,4) 
    plt.imshow(im_DoG, cmap='gray') 
    plt.colorbar(fraction=0.046) 
    plt.xticks([]), plt.yticks([]) 

通知的灰度值對每個圖像。

enter image description here

+0

我用CONV 2版本,因爲它的速度更快(例如convolve2d 1.67s VS CONV2 0.17s上512 * 512的圖像以5x5的內核)和速度是另一個應用的關鍵。但是這裏使用convolve2d是有意義的。 – WBM