one Dimensional gauss convolution function in Matlab
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
Hani
Updated on July 18, 2022Comments
-
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 over 14 yearsThanks 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 over 14 yearsWhat 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 over 14 yearsThe results will change with respect to sigma.
support
should be independent ofsigma
, it should only depend on the window size, which in your case seems to be a 1x7 vector. -
Hani over 14 yearsI 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 over 14 yearsAre there any other questions?
-
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.