3
$\begingroup$

I implemented a Wiener filter using Matlab and i noticed that both functions(mine and matlabs) are creating an image with shifted pixels on the edges. Class teacher said it will happen. Is there a simple explanation to that?

Code:

%open image
I = imread('pout.tif');

%sigma for gaussian
sigma = 1.2;
%gaussian kernel max width/height 
N = 2*ceil(3*sigma)+1;

%gaussian PSF(point spread function) 
PSF = fspecial('gaussian',N,sigma);

%Noise
NSR = 0.05;

%Matlab's Wiener function.
I1 = deconvwnr(I,PSF,NSR);

%New PSF for my implementation
PSF1 = zeros(N,N);
%loop to create the 2D gaussian psf.
x = (N/2)-0.5;
for i = -x:x
    for j = -x:x
        %gaussian 
         PSF1(i+x+1,j+x+1) = exp( -( ( (i^2) + (j^2) ) / ( 2 * (sigma^2) ) ) );
    end
end

%normalization
PSF1=PSF1/sum(sum(PSF1));

%fourier transformation of PSF1.
fouri = zeros(size(I,1),size(I,2));
fouri(1:N,1:N)= PSF1;
H = fft2(fouri);

%uint8 to double of the original image.
I = double(I);
%fourier transformation of the image
Y = fft2(I);
%Wiener function.
X = conj(H)./ ( abs(H).^2 + NSR ).*  Y;

%exit from fourier transformation.
I2 = real(ifft2(X));
%go back to uint8 for both images.
I2 = uint8(I2); 
I = uint8(I);

%Results.
subplot(1,3,1); imshow(I); title('Original');
subplot(1,3,2); imshow(I1); title('Matlab function');
subplot(1,3,3); imshow(I2); title('My implementation');

Output:

input and output shifted image

$\endgroup$
7
  • $\begingroup$ please clarify your question posting some code. $\endgroup$ Commented May 6, 2016 at 22:38
  • $\begingroup$ Can you please post the two images separately? Posting screenshots of the UI helps no one. $\endgroup$
    – Peter K.
    Commented May 7, 2016 at 0:10
  • $\begingroup$ Can you post the code? It will help. $\endgroup$
    – Amal
    Commented May 7, 2016 at 2:37
  • $\begingroup$ Added code. Removed image $\endgroup$ Commented May 7, 2016 at 9:24
  • $\begingroup$ This is usual behaviour for any filtering whether Wiener or not. Filtering is convolution and convloution operation will change the output image boundaries if the filter is not zero a phase type. Due to matlab indexing it wont be zero phase and the image will always be shifted by the group delay count of the filter impulse response. Furthermore even if you implement the filtering in frequency domain by multiplying DFTs of signal and filter impulse responses, a similar (circular) shift will happen and image will be delayed. You can compansate for such shifts by taking the "centre" of the result $\endgroup$
    – Fat32
    Commented May 7, 2016 at 13:28

1 Answer 1

1
$\begingroup$

The shift happens because of the way that the filter is defined in the spatial domain before applying the FFT. The kernel is centered on the pixel at index (N/2, N/2), instead of at (1, 1) (the top-left corner), where the FFT expects the origin to be.

Basically you convolve with a shifted kernel, which is identical to convolving with the non-shifted kernel and then shifting the output image.

This answer of mine on Stack Overflow shows how to properly pad and shift the kernel before applying the FFT. In short, pad the kernel equally on all sides, then apply ifftshift to shift the origin from the center of the array to the top-left corner.

$\endgroup$
1
  • $\begingroup$ OK, you answered it. Even better :-). I deleted the Wiki answer. $\endgroup$
    – Royi
    Commented Jul 17, 2023 at 5:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.