2013-06-19 28 views
12

5x5 boyutunda bir gauss filtresi oluşturmak için python kullanıyorum. Bu yazıyı here gördükten sonra benzer bir şeyden bahsediyorlar ama matlab işlevine eşdeğer python kodu almanın tam yolunu bulamadım fspecial('gaussian', f_wid, sigma) Bunu yapmak için başka bir yol var mı? Aşağıdaki kodu kullanarak çalıştı:Python'da bir gauss filtresi nasıl elde edilir

size = 2 
sizey = None 
size = int(size) 
if not sizey: 
    sizey = size 
else: 
    sizey = int(sizey) 
x, y = scipy.mgrid[-size: size + 1, -sizey: sizey + 1] 
g = scipy.exp(- (x ** 2/float(size) + y ** 2/float(sizey))) 
print g/np.sqrt(2 * np.pi) 

elde çıkışı

[[ 0.00730688 0.03274718 0.05399097 0.03274718 0.00730688] 
[ 0.03274718 0.14676266 0.24197072 0.14676266 0.03274718] 
[ 0.05399097 0.24197072 0.39894228 0.24197072 0.05399097] 
[ 0.03274718 0.14676266 0.24197072 0.14676266 0.03274718] 
[ 0.00730688 0.03274718 0.05399097 0.03274718 0.00730688]] 

İstediğim böyle bir şeydir: Eğer gerçekten alma veriyorsan Genel olarak

0.0029690 0.0133062 0.0219382 0.0133062 0.0029690 
    0.0133062 0.0596343 0.0983203 0.0596343 0.0133062 
    0.0219382 0.0983203 0.1621028 0.0983203 0.0219382 
    0.0133062 0.0596343 0.0983203 0.0596343 0.0133062 
    0.0029690 0.0133062 0.0219382 0.0133062 0.0029690 
+0

([python gerekli uzunlukta Gauss filtre oluşturma] olası çift http://stackoverflow.com/questions/11209115/oluşturma-gaussian-filtre-gerekli-uzunluk-python) ve http: // astrolitte rbox.blogspot.co.uk/2012/04/creating-discrete-gaussian-kernel-with.html – YXD

+0

Blogda belirtilen kodu kullanıyorum. I ', N set = 2 ve sigma = 1' ve aşağıdaki kodu kullanımı: sizeY değilse 'boyutu = 2 sizeY = Yok boyutu = int (boyut) : sizeY = boyut başka : sizeY = int (sizey) x, y = scipy.mgrid [-size: size + 1, -sizey: sizey + 1] g = scipy.exp (- (x ** 2/kayan (boyut) + y ** 2/float (sizey))/2) print g/np.sqrt (2 * np.pi) ' Ancak burada elde edilen sonuç, matlabda fspecial kullanılarak elde edilen formdan farklıdır – Khushboo

+0

Bu nasıl farklı? Ne bekliyorsunuz ve ne alıyorsunuz? – interjay

cevap

19

MATLAB ile tam olarak aynı sonucu elde etmenin en kolay yolu, doğrudan MATLAB fonksiyonunun kaynağına doğrudan bakmaktır. Bu durumda

, edit fspecial:

... 
    case 'gaussian' % Gaussian filter 

    siz = (p2-1)/2; 
    std = p3; 

    [x,y] = meshgrid(-siz(2):siz(2),-siz(1):siz(1)); 
    arg = -(x.*x + y.*y)/(2*std*std); 

    h  = exp(arg); 
    h(h<eps*max(h(:))) = 0; 

    sumh = sum(h(:)); 
    if sumh ~= 0, 
     h = h/sumh; 
    end; 
... 

Oldukça basit, ha?

import numpy as np 

def matlab_style_gauss2D(shape=(3,3),sigma=0.5): 
    """ 
    2D gaussian mask - should give the same result as MATLAB's 
    fspecial('gaussian',[shape],[sigma]) 
    """ 
    m,n = [(ss-1.)/2. for ss in shape] 
    y,x = np.ogrid[-m:m+1,-n:n+1] 
    h = np.exp(-(x*x + y*y)/(2.*sigma*sigma)) 
    h[ h < np.finfo(h.dtype).eps*h.max() ] = 0 
    sumh = h.sum() 
    if sumh != 0: 
     h /= sumh 
    return h 

Bu yuvarlama hatası dahilinde bana fspecial aynı cevabı verir: O < 10MINS Python için bağlantı noktasına bu işe bulunuyor

>> fspecial('gaussian',5,1) 

0.002969  0.013306  0.021938  0.013306  0.002969 
0.013306  0.059634  0.09832  0.059634  0.013306 
0.021938  0.09832  0.1621  0.09832  0.021938 
0.013306  0.059634  0.09832  0.059634  0.013306 
0.002969  0.013306  0.021938  0.013306  0.002969 

: matlab_style_gauss2D((5,5),1) 

array([[ 0.002969, 0.013306, 0.021938, 0.013306, 0.002969], 
     [ 0.013306, 0.059634, 0.09832 , 0.059634, 0.013306], 
     [ 0.021938, 0.09832 , 0.162103, 0.09832 , 0.021938], 
     [ 0.013306, 0.059634, 0.09832 , 0.059634, 0.013306], 
     [ 0.002969, 0.013306, 0.021938, 0.013306, 0.002969]]) 
+0

Tam olarak aradığım şey buydu. Ve gerçekten bunu basitleştirdiniz. Teşekkürler :) – Khushboo

-1

bu sorun için benzer bir çözüm bulundu:

def fspecial_gauss(size, sigma): 

    """Function to mimic the 'fspecial' gaussian MATLAB function 
    """ 

    x, y = numpy.mgrid[-size//2 + 1:size//2 + 1, -size//2 + 1:size//2 + 1] 
    g = numpy.exp(-((x**2 + y**2)/(2.0*sigma**2))) 
    return g/g.sum() 
0

Merhaba ben sorun Gauss filtre için normalizasyon faktörü kullandığınız kaç boyutlar bağlı olduğunu düşünüyorum. Bu yüzden filtre şu şekildedir: formula
Neleri kaçırdığınız normalleştirme faktörünün karesidir! Ve hesaplama doğruluğu nedeniyle tüm matrisi yeniden normalize etmeliyiz! kod buraya takılır:

def gaussian_filter(shape =(5,5), sigma=1): 
    x, y = [edge /2 for edge in shape] 
    grid = np.array([[((i**2+j**2)/(2.0*sigma**2)) for i in xrange(-x, x+1)] for j in xrange(-y, y+1)]) 
    g_filter = np.exp(-grid)/(2*np.pi*sigma**2) 
    g_filter /= np.sum(g_filter) 
    return g_filter 
print gaussian_filter() 

çıkış normalize olmadan 1 Özetle:

[[ 0.00291502 0.01306423 0.02153928 0.01306423 0.00291502] 
[ 0.01306423 0.05854983 0.09653235 0.05854983 0.01306423] 
[ 0.02153928 0.09653235 0.15915494 0.09653235 0.02153928] 
[ 0.01306423 0.05854983 0.09653235 0.05854983 0.01306423] 
[ 0.00291502 0.01306423 0.02153928 0.01306423 0.00291502]] 

çıkış np bölünür.toplamı (g_filter):

def gen_gaussian_kernel(shape, mean, var): 
    coors = [range(shape[d]) for d in range(len(shape))] 
    k = np.zeros(shape=shape) 
    cartesian_product = [[]] 
    for coor in coors: 
     cartesian_product = [x + [y] for x in cartesian_product for y in coor] 
    for c in cartesian_product: 
     s = 0 
     for cc, m in zip(c,mean): 
      s += (cc - m)**2 
     k[tuple(c)] = exp(-s/(2*var)) 
    return k 

bu fonksiyon gibi verilen şekil, merkezi ve varyans içeren bir normalize edilmemiş Gauss pencereleri verecektir: Burada

[[ 0.00296902 0.01330621 0.02193823 0.01330621 0.00296902] 
[ 0.01330621 0.0596343 0.09832033 0.0596343 0.01330621] 
[ 0.02193823 0.09832033 0.16210282 0.09832033 0.02193823] 
[ 0.01330621 0.0596343 0.09832033 0.0596343 0.01330621] 
[ 0.00296902 0.01330621 0.02193823 0.01330621 0.00296902]] 
0

bir nd-Gauss pencere jeneratör sağlamaktır. Örneğin : Sen bir ürünü olarak (çok bu deneyebilirsiniz

[[[ 0.22313016 0.36787944 0.22313016] 
    [ 0.36787944 0.60653066 0.36787944] 
    [ 0.22313016 0.36787944 0.22313016]] 

[[ 0.36787944 0.60653066 0.36787944] 
    [ 0.60653066 1.   0.60653066] 
    [ 0.36787944 0.60653066 0.36787944]] 

[[ 0.22313016 0.36787944 0.22313016] 
    [ 0.36787944 0.60653066 0.36787944] 
    [ 0.22313016 0.36787944 0.22313016]]] 
1

gen_gaussian_kernel (şekil = (3,3,3), ortalama = (1,1,1), var = 1.0) output-> 2 bağımsız 1D Gauss rastgele değişkenler) 2B Gauss çekirdek elde etmek üzere

from numpy import pi, exp, sqrt 
s, k = 1, 2 # generate a (2k+1)x(2k+1) gaussian kernel with mean=0 and sigma = s 
probs = [exp(-z*z/(2*s*s))/sqrt(2*pi*s*s) for z in range(-k,k+1)] 
kernel = np.outer(probs, probs) 
print kernel 

#[[ 0.00291502 0.00792386 0.02153928 0.00792386 0.00291502] 
#[ 0.00792386 0.02153928 0.05854983 0.02153928 0.00792386] 
#[ 0.02153928 0.05854983 0.15915494 0.05854983 0.02153928] 
#[ 0.00792386 0.02153928 0.05854983 0.02153928 0.00792386] 
#[ 0.00291502 0.00792386 0.02153928 0.00792386 0.00291502]] 

import matplotlib.pylab as plt 
plt.imshow(kernel) 
plt.colorbar() 
plt.show() 

enter image description here