I'm wondering what would be the easiest way to generate a 1D gaussian kernel in python given the filter length. I think that the idea is to evaluate the normal distribution for the values of the vector [-filter-length,...,filter_length], is it correct?
So far, I've done this, but I don't know why it is not correct:
result = np.zeros( filter_length )
mid = filter_length/2
result=[(1/(sigma*np.sqrt(2*np.pi)))*(1/(numpy.exp((i**2)/(2*sigma**2)))) for i in range(-mid,mid+1)]
return result
where sigma
is the standard deviation, which is a parameter. filter-length
is also a parameter.
It's incorrect because I get, for example, for length=3 and sigma=math.sqrt(1.0/2/math.log(2))
[0.23485931967491286, 0.46971863934982572, 0.23485931967491286]
And it should be:
[0.25, 0.5, 0.25]
So, is there any problem of rounding? I don't know what is going on...
Edit I think that I should truncate somehow
Problem Solved The problem was that I wasn't normalizing. I had to divide the vector by the sum of all its components.
Definition. The one-dimensional Gaussian filter has an impulse response given by. and the frequency response is given by the Fourier transform. with the ordinary frequency. These equations can also be expressed with the standard deviation as parameter.
The only difference between the two models is the K in the regularisation term. The key theoretical advantage of the kernel approach is that it allows you to interpret a non-linear model as a linear model following a fixed non-linear transformation that doesn't depend on the sample of data.
There's no formula to determine it for you; the optimal sigma will depend on image factors - primarily the resolution of the image and the size of your objects in it (in pixels).
I am not very firm with numpy syntax, but if you convolve a kernel with a dirac impulse, you get the same kernel as output.
So you could simply use the inbuild scipy.ndimage.filters.gaussian_filter1d function, and use this array as input: [ 0, 0, 0, ... 0, 1, 0, ...0, 0, 0]
The output should be a gaussian kernel, with a value of 1 at its peak. (replace 1 with the maximum you want in your desired kernel)
So in essence, you will get the Gaussian kernel that gaussian_filter1d function uses internally as the output. This should be the simplest and least error-prone way to generate a Gaussian kernel, and you can use the same approach to generate a 2d kernel, with the respective scipy 2d function. Of course if the goal is to do it from scratch, then this approach is only good as a reference
In regards to your equation:
to get [..., 0.5, ...] as the output with your formula, you need to solve(1/(sigma*np.sqrt(2*np.pi)) = 0.5
so the correct sigma should besigma = math.sqrt(2*1/np.pi)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With