Reputation: 11
Hi i have to apply Gaussian filter to an image without using imfilter and fspecial functions. I wrote a code like this, but it doesn't work:
I=imread('IMG.tif');
[row,col]=size(I);
k=input('k girin');
s=input('sigma girin');
for i=1:row
for j=1:col
h(i,j)=(1/2*pi*s^2)*exp(-((i-k-1)^2 + (j-k-1)^2)/2*s^2);
end
end
I don't have any idea how can i apply gaussian filter without these functions. Can you please help me ? Thanks.
Upvotes: 1
Views: 2943
Reputation: 39389
It looks like the line
h(i,j)=(1/2*pi*s^2)*exp(-((i-k-1)^2 + (j-k-1)^2)/2*s^2);
Simply generates an element of the Gaussian filter, but does not multiply it by the corresponding image pixel. Essentially, the problem is that you are not doing a convolution here at all.
A better way to do this is first to create the filter of the given size and sigma. Display the filter using imshow
to make sure it looks right. Then write the code to do the convolution. Hint: there should be two nested loops over the filter inside two nested loops over the image.
Edit: if all you are trying to do so far is to create the filter, then you have some other issues. First, you should pre-allocate the filter using the zeros
function. Second, your filter should not be the size of the image. It should be something small, like 5x5 or 9x9. In your code the loops iterate over all the pixels in the image, which would make the filter the same size as the image.
Upvotes: 0
Reputation: 721
The easiest way to do this is in the fourier domain using the fourier convolution theorem. This theorem simply states that convolution in the spatial domain is multiplication in the fourier domain. Since the fourier transform of a gaussian is a gaussian this makes the problem even easier. No loops required. Something such as this would work:
sigma = input('Input a standard deviation in the fourier domain: ');
im=imread('peppers.png');
[rows,cols,bands]=size(im);
%make the meshgrid of coordinates
x=1:cols;y=1:rows;
[X,Y] = meshgrid(x,y);
%compute the filter in the fourier domain,
%centered top right so we dont need to shift
filter = mvnpdf([X(:) Y(:)],[0 0]',sigma.*eye(2));
filter = reshape(filter,[rows,cols]);
%convolution theorem
im_fft = fft2(im);
im_filt = ifft(im_fft.*repmat(filter,[1,1,bands]));
%display
figure;subplot(1,2,1);imagesc(im);title('Original image');
subplot(1,2,2);imagesc(im_filt);title('Filtered Image');
Upvotes: 0
Reputation: 4956
In place of imfilter
, there are several options.
You can use filter2
or xcorr2
. It basically do the same thing, except on boundaries (zero padding is the only rule). The function conv2
is the same one, with symmetrizing the kernel (filter2
calls conv2
in fact). So all you need is to extend your image on boundaries, fill the boundaries according to your rule, filter the image, and then remove the boundaries from the result image.
As for fspecial
, this helpful function designs predefined filters. In the doc, the formulas of these filters are written, so it is quite straightforward to implement. You can also have a look at this post for a code sample.
EDIT: here is a code to generate a gaussian filter of size [2*N1+1,2*N2+1]
and with standard deviations (along x and y) [s1,s2]
:
h = exp(-(-N1:N1).^2/(2*s1^2)).'*exp(-(-N2:N2).^2/(2*s2^2));
h = h/sum(h(:));
Upvotes: 1