The problem formally is stated as ( from Wikipedia ):
where,
x(t) - is some input signal (unknown) at time
h(t) - is the known impulse response of a linear time-invariant system (PSF - point spread function)
y(t) - observed signal (input image in our case)
Our goal is to find some g(t) so we can estimate x'(t) so:
x'(t) is our deconvoluted, de-noised image.
Long story short solution for this is in frequency domain where:
For more information go to wiki.
N(f) and S(f) in equation above are power spectrums of noise and signal.
(power spectrum is squared magnitude of Fourier transform)
But what can we do, if we don't have any H(f) ( aka. PSF - point spread function ) and we just want Wiener filter to do noise removal for us? We can replace it with 1 and simplify equation which gives us:
And where can we find power spectra of noise ( N(f) ) and signal ( S(f) )? Thing with noise is quite easy. Since it's additive Gaussian noise we just need to know it's standard deviation to compute power spectrum (which is flat).
With signal it seems to be quite problematic. You can ask: what the fuck? Do I need to know clear signal to obtain clear signal? Luckily power spectra of real images are quite alike. It shows up that you can use previously prepared spectrum to denoise unknown images with good accuracy. So, for testing purpose just take the power spectrum of sample image.
So, enough of theory and let's get to code. I've written sample program using C++ and OpenCV. Code available at github:
https://github.com/yakxxx/wiener2
here are sample effects of filter:
1. Clear image:
2. Noised image ( additive Gaussian noise - --noise-stddev=50 )
3. De-noised image: