From a8e9a3a88df83ae118b54e975056c687ac3d30d2 Mon Sep 17 00:00:00 2001 From: Karpushin Vladislav Date: Tue, 24 Jul 2018 16:54:17 +0700 Subject: [PATCH] doc: add new tutorial "Out of focus deblur filter" In this tutorial you will learn: - what is a degradation image model - what is a PSF of an out-of-focus image - how to restore a blurred image - what is the Wiener filter --- doc/opencv.bib | 14 ++ .../images/original.jpg | Bin 0 -> 14447 bytes .../out_of_focus_deblur_filter/images/psf.png | Bin 0 -> 630 bytes .../images/recovered.jpg | Bin 0 -> 42725 bytes .../out_of_focus_deblur_filter.markdown | 112 +++++++++++++ .../imgproc/table_of_content_imgproc.markdown | 10 ++ .../out_of_focus_deblur_filter.cpp | 149 ++++++++++++++++++ 7 files changed, 285 insertions(+) create mode 100755 doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg create mode 100755 doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png create mode 100755 doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg create mode 100755 doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown create mode 100755 samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp diff --git a/doc/opencv.bib b/doc/opencv.bib index edb7033e8d..7c8303f7f4 100644 --- a/doc/opencv.bib +++ b/doc/opencv.bib @@ -1016,3 +1016,17 @@ year = {2017}, organization = {IEEE} } + +@ARTICLE{gonzalez, + title={Digital Image Fundamentals, Digital Imaging Processing}, + author={Gonzalez, Rafael C and others}, + year={1987}, + publisher={Addison Wesley Publishing Company} +} + +@ARTICLE{gruzman, + title={Цифровая обработка изображений в информационных системах}, + author={Грузман, И.С. and Киричук, В.С. and Косых, В.П. and Перетягин, Г.И. and Спектор, А.А.}, + year={2000}, + publisher={Изд-во НГТУ Новосибирск} +} diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg new file mode 100755 index 0000000000000000000000000000000000000000..ecd23c89f947e994f5e3a84d34e0ffee3802508e GIT binary patch literal 14447 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 literal 0 HcmV?d00001 diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png new file mode 100755 index 0000000000000000000000000000000000000000..3835124db8501778e3ac6f8081db07966e6ff70f GIT binary patch literal 630 zcmeAS@N?(olHy`uVBq!ia0vp^zd)D+NHDBzXMM=Pz+~&`;uuoF`1GLRq#JAkM;spf z?~hx)YEr4Y+F^#flT;%IC;GH>^7|9!efB5BpD-VfPw{)!_g^)6Q`w*9oRil+GDl8Y z`Pkh^#rwE^ihEmM{K=j-GW;jHz{DAu{u3Q*WcW|Efr%cO{*x^TB1cC5L=#TJM`rzr z2Ar~B34~E#7Q&)4AbY_s024g2`zJ|8TGc698mdKI;Vst0Ls7legFUf literal 0 HcmV?d00001 diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg new file mode 100755 index 0000000000000000000000000000000000000000..2794d427d750448b6bd947504907688e9bda9c92 GIT binary patch literal 42725 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%0AIXn|!)38ECHv_L9eAg!u7lf31 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 literal 0 HcmV?d00001 diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown b/doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown new file mode 100755 index 0000000000..abab071208 --- /dev/null +++ b/doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown @@ -0,0 +1,112 @@ +Out-of-focus Deblur Filter {#tutorial_out_of_focus_deblur_filter} +========================== + +Goal +---- + +In this tutorial you will learn: + +- what is a degradation image model +- what is PSF of out-of-focus image +- how to restore a blurred image +- what is Wiener filter + +Theory +------ + +@note The explanation is based on the books @cite gonzalez and @cite gruzman. Also, you can refer to Matlab's tutorial [Image Deblurring in Matlab] and an article [SmartDeblur]. +@note An out-of-focus image on this page is a real world image. An out-of-focus was done manually by camera optics. + +### What is a degradation image model? + +A mathematical model of the image degradation in frequency domain representation is: + +\f[S = H\cdot U + N\f] + +where +\f$S\f$ is a spectrum of blurred (degraded) image, +\f$U\f$ is a spectrum of original true (undegraded) image, +\f$H\f$ is frequency response of point spread function (PSF), +\f$N\f$ is a spectrum of additive noise. + +Circular PSF is a good approximation of out-of-focus distortion. Such PSF is specified by only one parameter - radius \f$R\f$. Circular PSF is used in this work. + +![Circular point spread function](psf.png) + +### How to restore an blurred image? + +The objective of restoration (deblurring) is to obtain an estimate of the original image. Restoration formula in frequency domain is: + +\f[U' = H_w\cdot S\f] + +where +\f$U'\f$ is spectrum of estimation of original image \f$U\f$, +\f$H_w\f$ is restoration filter, for example, Wiener filter. + +### What is Wiener filter? + +Wiener filter is a way to restore a blurred image. Let's suppose that PSF is a real and symmetric signal, a power spectrum of the original true image and noise are not known, +then simplified Wiener formula is: + +\f[H_w = \frac{H}{|H|^2+\frac{1}{SNR}} \f] + +where +\f$SNR\f$ is signal-to-noise ratio. + +So, in order to recover an out-of-focus image by Wiener filter, it needs to know \f$SNR\f$ and \f$R\f$ of circular PSF. + + +Source code +----------- + +You can find source code in the `samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp` of the OpenCV source code library. + +@include cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp + +Explanation +----------- + +An out-of-focus image recovering algorithm consists of PSF generation, Wiener filter generation and filtering an blurred image in frequency domain: +@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp main + +A function calcPSF() forms an circular PSF according to input parameter radius \f$R\f$: +@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp calcPSF + +A function calcWnrFilter() synthesizes simplified Wiener filter \f$H_w\f$ according to formula described above: +@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp calcWnrFilter + +A function fftshift() rearranges PSF. This code was just copied from tutorial @ref tutorial_discrete_fourier_transform "Discrete Fourier Transform": +@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp fftshift + +A function filter2DFreq() filters an blurred image in frequency domain: +@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp filter2DFreq + +Result +------ + +Below you can see real out-of-focus image: +![Out-of-focus image](images/original.jpg) + + +Below result was done by \f$R\f$ = 53 and \f$SNR\f$ = 5200 parameters: +![The restored (deblurred) image](images/recovered.jpg) + +The Wiener filter was used, values of \f$R\f$ and \f$SNR\f$ were selected manually to give the best possible visual result. +We can see that the result is not perfect, but it gives us a hint to the image content. With some difficulty, the text is readable. + +@note The parameter \f$R\f$ is the most important. So you should adjust \f$R\f$ first, then \f$SNR\f$. +@note Sometimes you can observe the ringing effect in an restored image. This effect can be reduced by several methods. For example, you can taper input image edges. + +You can also find a quick video demonstration of this on +[YouTube](https://youtu.be/0bEcE4B0XP4). +@youtube{0bEcE4B0XP4} + +References +------ +- [Image Deblurring in Matlab] - Image Deblurring in Matlab +- [SmartDeblur] - SmartDeblur site + + +[Digital Image Processing]: http://web.ipac.caltech.edu/staff/fmasci/home/astro_refs/Digital_Image_Processing_2ndEd.pdf +[Image Deblurring in Matlab]: https://www.mathworks.com/help/images/image-deblurring.html +[SmartDeblur]: http://yuzhikov.com/articles/BlurredImagesRestoration1.htm diff --git a/doc/tutorials/imgproc/table_of_content_imgproc.markdown b/doc/tutorials/imgproc/table_of_content_imgproc.markdown index 59c985e1dd..3d82c0cf53 100644 --- a/doc/tutorials/imgproc/table_of_content_imgproc.markdown +++ b/doc/tutorials/imgproc/table_of_content_imgproc.markdown @@ -292,3 +292,13 @@ In this section you will learn about the image processing (manipulation) functio *Author:* Theodore Tsesmelis Where we learn to segment objects using Laplacian filtering, the Distance Transformation and the Watershed algorithm. + +- @subpage tutorial_out_of_focus_deblur_filter + + *Languages:* C++ + + *Compatibility:* \> OpenCV 2.0 + + *Author:* Karpushin Vladislav + + You will learn how to recover an out-of-focus image by Wiener filter. diff --git a/samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp b/samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp new file mode 100755 index 0000000000..059df8bd55 --- /dev/null +++ b/samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp @@ -0,0 +1,149 @@ +/** +* @brief You will learn how to recover an out-of-focus image by Wiener filter +* @author Karpushin Vladislav, karpushin@ngs.ru, https://github.com/VladKarpushin +*/ +#include +#include "opencv2/imgproc.hpp" +#include "opencv2/imgcodecs.hpp" + +using namespace cv; +using namespace std; + +void help(); +void calcPSF(Mat& outputImg, Size filterSize, int R); +void fftshift(const Mat& inputImg, Mat& outputImg); +void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H); +void calcWnrFilter(const Mat& input_h_PSF, Mat& output_G, double nsr); + +const String keys = +"{help h usage ? | | print this message }" +"{image |original.JPG | input image name }" +"{R |53 | radius }" +"{SNR |5200 | signal to noise ratio}" +; + +int main(int argc, char *argv[]) +{ + help(); + CommandLineParser parser(argc, argv, keys); + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + + int R = parser.get("R"); + int snr = parser.get("SNR"); + string strInFileName = parser.get("image"); + + if (!parser.check()) + { + parser.printErrors(); + return 0; + } + + Mat imgIn; + imgIn = imread(strInFileName, IMREAD_GRAYSCALE); + if (imgIn.empty()) //check whether the image is loaded or not + { + cout << "ERROR : Image cannot be loaded..!!" << endl; + return -1; + } + + Mat imgOut; + +//! [main] + // it needs to process even image only + Rect roi = Rect(0, 0, imgIn.cols & -2, imgIn.rows & -2); + + //Hw calculation (start) + Mat Hw, h; + calcPSF(h, roi.size(), R); + calcWnrFilter(h, Hw, 1.0 / double(snr)); + //Hw calculation (stop) + + // filtering (start) + filter2DFreq(imgIn(roi), imgOut, Hw); + // filtering (stop) +//! [main] + + imgOut.convertTo(imgOut, CV_8U); + normalize(imgOut, imgOut, 0, 255, NORM_MINMAX); + imwrite("result.jpg", imgOut); + return 0; +} + +void help() +{ + cout << "2018-07-12" << endl; + cout << "DeBlur_v8" << endl; + cout << "You will learn how to recover an out-of-focus image by Wiener filter" << endl; +} + +//! [calcPSF] +void calcPSF(Mat& outputImg, Size filterSize, int R) +{ + Mat h(filterSize, CV_32F, Scalar(0)); + Point point(filterSize.width / 2, filterSize.height / 2); + circle(h, point, R, 255, -1, 8); + Scalar summa = sum(h); + outputImg = h / summa[0]; +} +//! [calcPSF] + +//! [fftshift] +void fftshift(const Mat& inputImg, Mat& outputImg) +{ + outputImg = inputImg.clone(); + int cx = outputImg.cols / 2; + int cy = outputImg.rows / 2; + Mat q0(outputImg, Rect(0, 0, cx, cy)); + Mat q1(outputImg, Rect(cx, 0, cx, cy)); + Mat q2(outputImg, Rect(0, cy, cx, cy)); + Mat q3(outputImg, Rect(cx, cy, cx, cy)); + Mat tmp; + q0.copyTo(tmp); + q3.copyTo(q0); + tmp.copyTo(q3); + q1.copyTo(tmp); + q2.copyTo(q1); + tmp.copyTo(q2); +} +//! [fftshift] + +//! [filter2DFreq] +void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H) +{ + Mat planes[2] = { Mat_(inputImg.clone()), Mat::zeros(inputImg.size(), CV_32F) }; + Mat complexI; + merge(planes, 2, complexI); + dft(complexI, complexI, DFT_SCALE); + + Mat planesH[2] = { Mat_(H.clone()), Mat::zeros(H.size(), CV_32F) }; + Mat complexH; + merge(planesH, 2, complexH); + Mat complexIH; + mulSpectrums(complexI, complexH, complexIH, 0); + + idft(complexIH, complexIH); + split(complexIH, planes); + outputImg = planes[0]; +} +//! [filter2DFreq] + +//! [calcWnrFilter] +void calcWnrFilter(const Mat& input_h_PSF, Mat& output_G, double nsr) +{ + Mat h_PSF_shifted; + fftshift(input_h_PSF, h_PSF_shifted); + Mat planes[2] = { Mat_(h_PSF_shifted.clone()), Mat::zeros(h_PSF_shifted.size(), CV_32F) }; + Mat complexI; + merge(planes, 2, complexI); + dft(complexI, complexI); + split(complexI, planes); + Mat denom; + pow(abs(planes[0]), 2, denom); + denom += nsr; + divide(planes[0], denom, output_G); +} +//! [calcWnrFilter]