2013-06-19 59 views
12

Tôi đang sử dụng python để tạo bộ lọc gaussian có kích thước 5x5. Tôi thấy bài đăng này here nơi họ nói về một điều tương tự nhưng tôi không tìm thấy cách chính xác để lấy mã python tương đương với chức năng MATLAB fspecial('gaussian', f_wid, sigma) Có cách nào khác để làm điều đó không? tôi đã cố gắng sử dụng đoạn mã sau:Cách lấy bộ lọc gaussian trong python

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) 

Kết quả thu được là

[[ 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]] 

Những gì tôi muốn một cái gì đó như thế này là:

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

thể trùng lặp của [Tạo bộ lọc Gaussian chiều dài yêu cầu trong python] (http://stackoverflow.com/questions/11209115/create-gaussian-filter-of-required-length-in-python) và http: // astrolitte rbox.blogspot.co.uk/2012/04/creating-discrete-gaussian-kernel-with.html – YXD

+0

Tôi đang sử dụng mã được đề cập trong blog. Tôi đặt 'N = 2 và sigma = 1' và sử dụng đoạn mã sau: ' size = 2 sizey = Không kích thước = int (size) nếu không sizey: sizey = kích thước khác: sizey = int (sizey) x, y = scipy.mgrid [-size: size + 1, -sizey: sizey + 1] g = scipy.exp (- (x ** 2/float (kích thước) + y ** 2/float (sizey))/2) in g/np.sqrt (2 * np.pi) ' Nhưng kết quả thu được ở đây là hình thức khác nhau mà ta thu được bằng cách sử dụng fspecial trong MATLAB – Khushboo

+0

Nó khác nhau như thế nào? Những gì bạn mong đợi và những gì bạn nhận được? – interjay

Trả lời

19

Nói chung nếu bạn thực sự quan tâm về việc kết quả chính xác giống như MATLAB, cách dễ nhất để đạt được điều này thường là nhìn trực tiếp vào nguồn của hàm MATLAB.

Trong trường hợp này, 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; 
... 

Khá đơn giản, eh? Đó là < 10 phút làm việc với cảng này để Python:

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 

này mang lại cho tôi câu trả lời tương tự như fspecial để trong vòng tròn lỗi:

>> 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

Thats chính xác những gì tôi đang tìm kiếm. Và bạn thực sự làm cho nó đơn giản. Cảm ơn :) – Khushboo

1

Chức năng này thực hiện chức năng tương tự như fspecial trong matlab

http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.get_window.html từ tín hiệu nhập scipy

>>>signal.get_window(('gaussian',2),3) 
>>>array([ 0.8824969, 1.  , 0.8824969]) 

Chức năng này dường như chỉ tạo ra hạt nhân 1D

Tôi đoán bạn có thể triển khai mã để tạo mặt nạ Gaussian cho chính bạn cũng như cách khác đã chỉ ra.

-1

tôi tìm thấy giải pháp tương tự cho vấn đề này:

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

Hi Tôi nghĩ vấn đề là đối với một bộ lọc gaussian yếu tố bình thường phụ thuộc vào có bao nhiêu kích thước mà bạn sử dụng. Vì vậy, bộ lọc trông như thế này formula
Điều bạn bỏ lỡ là hình vuông của hệ số chuẩn hóa! Và cần phải chuẩn hóa lại toàn bộ ma trận vì tính chính xác của máy tính! Mã này được gắn ở đây:

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() 

Sản lượng mà không bình thường để tổng hợp 1:

[[ 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]] 

Sản lượng chia cho np.sum (g_filter):

[[ 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

ở đây là để cung cấp một máy phát điện cửa sổ nd-gaussian:

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 

chức năng này sẽ cung cấp cho bạn một cửa sổ gaussian unnormalized với hình dạng nhất định, trung tâm, và phương sai. ví dụ: gen_gaussian_kernel (hình = (3,3,3), có nghĩa là = (1,1,1), var = 1.0) output->

[[[ 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

Bạn có thể thử này quá (như sản phẩm của 2 độc lập 1D Gaussian biến ngẫu nhiên) để có được một 2D Gaussian Kernel:

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

Các vấn đề liên quan