one Dimensional gauss convolution function in Matlab

10,331

Solution 1

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)

Solution 2

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

Share:
10,331
Hani
Author by

Hani

Updated on July 18, 2022

Comments

  • Hani
    Hani almost 2 years

    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.

  • Hani
    Hani over 14 years
    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
    Hani over 14 years
    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?
  • Harsh Pathak
    Harsh Pathak over 14 years
    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.
  • Hani
    Hani over 14 years
    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.
  • Harsh Pathak
    Harsh Pathak over 14 years
    Are there any other questions?
  • rayryeng
    rayryeng almost 10 years
    +1 back (I actually +1'ed this a long time ago!) Very nice if you don't have the Image Processing Toolbox.