views:

510

answers:

2

Hello, I am trying to write a function that returns a one dimentional gauss filter. the function took sigma as a parameter. The problem is that the function returns the same array for all sigmas.

  function gaussFilter=gauss(sigma)  
  width = 3 * sigma;  
  support = (-width :sigma: width);  
  gaussFilter= exp( - (support).^2 / (2*sigma^2));   
  gaussFilter = gaussFilter/ sum(gaussFilter);

Note that support array is calculated correctly but the problem arise when applying the exp.

+4  A: 

There is nothing wrong with the results. Your support vector is essentially,

[-3*sigma -2*sigma -1*sigma 0 1*sigma 2*sigma 3*sigma]

And if you square each element of support and multiply by -1, -support.^2

[-9*sigma^2 -4*sigma^2 -1*sigma^2 0 -1*sigma^2 -4*sigma^2 -9*sigma^2]

So dividing it by 2*sigma^2 will always result in the same vector,

[-9/2 -4/2 -1/2 0 -1/2 -4/2 -9/2]

Or

-4.5000   -2.0000   -0.5000         0   -0.5000   -2.0000   -4.5000

So that's why you always get the same answer.

So you need to check your algorithm for making a one-dimensional gaussian filter.

EDIT:

Your original code is fine: except I don't understand why you've made support with -3*sigma:sigma:3*sigma - you should change it to support = -3:3.

You can also use:

gaussFilter = fspecial('gaussian',[1 7],sigma)

EDIT: Check out Amro's solution for the full code and explanation why support = -3*sigma:3*sigma and not support = -3*sigma:sigma:3*sigma

Jacob
Thanks very much,but i dont want to apply for loop. I would like to use a vector (support) instead.Please could you tell me how to do it.
Hani
What you wrote is correct for sigma=1,but 3*sigma:sigma:3*sigma will give me six elements with sigma between each two.thanks for fspecial advice but i dont want to use a built in one.But even with support=-3:3 the results will be the same, wont it?
Hani
The results will change with respect to sigma. `support` should be independent of `sigma`, it should only depend on the window size, which in your case seems to be a 1x7 vector.
Jacob
I am sorry for my heavy questions, but could you please correct my code and give me the whole correct one depending on my code..I am so sorry again.
Hani
Are there any other questions?
Jacob
A: 

The idea is that the filter needs to be wide enough to represent the Gaussian function. The rule of thumb is to use filter size of at least 6*sigma.

Since the support needs to be centered around zero, that would give you the range of -3*sigma to +3*sigma (to be more accurate, it is -/+ round(6*sigma - 1)/2 to account for the zero in the middle). Hence:

function gaussFilter = gauss(sigma)
    width = round((6*sigma - 1)/2);
    support = (-width:width);
    gaussFilter = exp( -(support).^2 ./ (2*sigma^2) );
    gaussFilter = gaussFilter/ sum(gaussFilter);

Example: (all the following are equivalent)

sigma = 1.2;
width = round((6*sigma - 1)/2);

gauss(sigma)

normpdf( -width:width, 0, sigma )

fspecial('gaussian', [1 2*width+1], sigma)

h = gausswin(2*width+1)';
h = h / sum(h)
Amro

related questions