├── BlurDetectionFFT.cbp
├── Lena.jpg
├── Lena_1.jpg
├── Lena_10.jpg
├── Lena_1_5.jpg
├── Lena_2.jpg
├── Lena_3.jpg
├── Lena_5.jpg
├── README.md
└── main.cpp
/BlurDetectionFFT.cbp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Lena.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena.jpg
--------------------------------------------------------------------------------
/Lena_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena_1.jpg
--------------------------------------------------------------------------------
/Lena_10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena_10.jpg
--------------------------------------------------------------------------------
/Lena_1_5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena_1_5.jpg
--------------------------------------------------------------------------------
/Lena_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena_2.jpg
--------------------------------------------------------------------------------
/Lena_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena_3.jpg
--------------------------------------------------------------------------------
/Lena_5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Qengineering/Blur-detection-with-FFT-in-C/9c182424afbf44f3bce04a8ed1bca9afc7d656da/Lena_5.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blur-detection-with-FFT-in-C
2 | 
3 | This is a C++ implementation of the blur detection written in Python.
4 | https://github.com/whdcumt/BlurDetection.
5 | Paper: http://www.cse.cuhk.edu.hk/leojia/all_final_papers/blur_detect_cvpr08.pdf
6 | As known, blur is the lack of detailed features in an image. Detailed features have the most energy in the high-frequency Fourier spectrum. As to blurry regions (clouds, for instance), which have energy levels in low frequencies. This fact lets the blur detecting work. After removing the low frequencies, the energy of the remaining high part is measured. The higher output, the sharper the image must be. Please note, you should have OpenCV installed.
7 |
8 | ------------
9 |
10 | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CPZTM5BB3FCYL)
11 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using namespace cv;
5 | using namespace std;
6 |
7 | #define BLOCK 60
8 |
9 | int main(int argc, char **argv) {
10 | if (argc <= 1) {
11 | fprintf(stderr, "Error: missing image file\n");
12 | return 1;
13 | }
14 | string image_file = argv[1];
15 |
16 | cout << "Processing " << image_file << std::endl;
17 | Mat frame = imread(image_file, IMREAD_GRAYSCALE);
18 |
19 | int cx = frame.cols/2;
20 | int cy = frame.rows/2;
21 |
22 | // Go float
23 | Mat fImage;
24 | frame.convertTo(fImage, CV_32F);
25 |
26 | // FFT
27 | cout << "Direct transform...\n";
28 | Mat fourierTransform;
29 | dft(fImage, fourierTransform, DFT_SCALE|DFT_COMPLEX_OUTPUT);
30 |
31 | //center low frequencies in the middle
32 | //by shuffling the quadrants.
33 | Mat q0(fourierTransform, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
34 | Mat q1(fourierTransform, Rect(cx, 0, cx, cy)); // Top-Right
35 | Mat q2(fourierTransform, Rect(0, cy, cx, cy)); // Bottom-Left
36 | Mat q3(fourierTransform, Rect(cx, cy, cx, cy)); // Bottom-Right
37 |
38 | Mat tmp; // swap quadrants (Top-Left with Bottom-Right)
39 | q0.copyTo(tmp);
40 | q3.copyTo(q0);
41 | tmp.copyTo(q3);
42 |
43 | q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
44 | q2.copyTo(q1);
45 | tmp.copyTo(q2);
46 |
47 | // Block the low frequencies
48 | // #define BLOCK could also be a argument on the command line of course
49 | fourierTransform(Rect(cx-BLOCK,cy-BLOCK,2*BLOCK,2*BLOCK)).setTo(0);
50 |
51 | //shuffle the quadrants to their original position
52 | Mat orgFFT;
53 | fourierTransform.copyTo(orgFFT);
54 | Mat p0(orgFFT, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
55 | Mat p1(orgFFT, Rect(cx, 0, cx, cy)); // Top-Right
56 | Mat p2(orgFFT, Rect(0, cy, cx, cy)); // Bottom-Left
57 | Mat p3(orgFFT, Rect(cx, cy, cx, cy)); // Bottom-Right
58 |
59 | p0.copyTo(tmp);
60 | p3.copyTo(p0);
61 | tmp.copyTo(p3);
62 |
63 | p1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
64 | p2.copyTo(p1);
65 | tmp.copyTo(p2);
66 |
67 | // IFFT
68 | cout << "Inverse transform...\n";
69 | Mat invFFT;
70 | Mat logFFT;
71 | double minVal,maxVal;
72 |
73 | dft(orgFFT, invFFT, DFT_INVERSE|DFT_REAL_OUTPUT);
74 |
75 | //img_fft = 20*numpy.log(numpy.abs(img_fft))
76 | invFFT = cv::abs(invFFT);
77 | cv::minMaxLoc(invFFT,&minVal,&maxVal,NULL,NULL);
78 |
79 | //check for impossible values
80 | if(maxVal<=0.0){
81 | cerr << "No information, complete black image!\n";
82 | return 1;
83 | }
84 |
85 | cv::log(invFFT,logFFT);
86 | logFFT *= 20;
87 |
88 | //result = numpy.mean(img_fft)
89 | cv::Scalar result= cv::mean(logFFT);
90 | cout << "Result : "<< result.val[0] << endl;
91 |
92 | // show if you like
93 | Mat finalImage;
94 | logFFT.convertTo(finalImage, CV_8U); // Back to 8-bits
95 | imshow("Input", frame);
96 | imshow("Result", finalImage);
97 | cv::waitKey();
98 | // end show if you like
99 |
100 | return 0;
101 | }
102 |
--------------------------------------------------------------------------------