7

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.

Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319
Hani
  • 1,517
  • 5
  • 20
  • 28

2 Answers2

4

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

Community
  • 1
  • 1
Jacob
  • 34,255
  • 14
  • 110
  • 165
  • 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 Dec 02 '09 at 14:34
  • 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 Dec 02 '09 at 15:14
  • 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 Dec 02 '09 at 16:52
  • 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 Dec 02 '09 at 17:54
  • Are there any other questions? – Jacob Dec 05 '09 at 14:54
4

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
  • 123,847
  • 25
  • 243
  • 454
  • +1 back (I actually +1'ed this a long time ago!) Very nice if you don't have the Image Processing Toolbox. – rayryeng Jul 06 '14 at 22:34