1 /*
2  * test-image-deblurring.cpp - test image deblurring
3  *
4  *  Copyright (c) 2017 Intel Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Andrey Parfenov <a1994ndrey@gmail.com>
19  * Author: Wind Yuan <feng.yuan@intel.com>
20  */
21 
22 #include "test_common.h"
23 #include "test_inline.h"
24 
25 #include <unistd.h>
26 #include <getopt.h>
27 #include <image_file_handle.h>
28 #include <ocl/cv_image_sharp.h>
29 #include <ocl/cv_wiener_filter.h>
30 #include <ocl/cv_image_deblurring.h>
31 
32 #include <opencv2/opencv.hpp>
33 #include <opencv2/core/ocl.hpp>
34 
35 using namespace XCam;
36 
37 static void
usage(const char * arg0)38 usage (const char* arg0)
39 {
40     printf ("Usage: %s --input file --output file\n"
41             "\t--input,    input image(RGB)\n"
42             "\t--output,   output image(RGB) PREFIX\n"
43             "\t--blind,    optional, blind or non-blind deblurring, default true; select from [true/false]\n"
44             "\t--save,     optional, save file or not, default true; select from [true/false]\n"
45             "\t--help,     usage\n",
46             arg0);
47 }
48 
49 static void
blind_deblurring(cv::Mat & input_image,cv::Mat & output_image)50 blind_deblurring (cv::Mat &input_image, cv::Mat &output_image)
51 {
52     SmartPtr<CVImageDeblurring> image_deblurring = new CVImageDeblurring ();
53     cv::Mat kernel;
54     image_deblurring->blind_deblurring (input_image, output_image, kernel, -1, -1, false);
55 }
56 
57 static void
non_blind_deblurring(cv::Mat & input_image,cv::Mat & output_image)58 non_blind_deblurring (cv::Mat &input_image, cv::Mat &output_image)
59 {
60     SmartPtr<CVWienerFilter> wiener_filter = new CVWienerFilter ();
61     cv::cvtColor (input_image, input_image, CV_BGR2GRAY);
62     // use simple motion blur kernel
63     int kernel_size = 13;
64     cv::Mat kernel = cv::Mat::zeros (kernel_size, kernel_size, CV_32FC1);
65     for (int i = 0; i < kernel_size; i++)
66     {
67         kernel.at<float> ((kernel_size - 1) / 2, i) = 1.0;
68     }
69     kernel /= kernel_size;
70     //flip kernel to perform convolution
71     cv::Mat conv_kernel;
72     cv::flip (kernel, conv_kernel, -1);
73     cv::Mat blurred;
74     cv::filter2D (input_image, blurred, CV_32FC1, conv_kernel, cv::Point(-1, -1), 0, cv::BORDER_CONSTANT);
75     // restore the image
76     cv::Mat median_blurred;
77     medianBlur (blurred, median_blurred, 3);
78     SmartPtr<CVImageProcessHelper> helpers = new CVImageProcessHelper ();
79     float noise_power = 1.0f / helpers->get_snr (blurred, median_blurred);
80     wiener_filter->wiener_filter (blurred, kernel, output_image, noise_power);
81 }
82 
main(int argc,char * argv[])83 int main (int argc, char *argv[])
84 {
85     const char *file_in_name = NULL;
86     const char *file_out_name = NULL;
87 
88     bool need_save_output = true;
89     bool blind = true;
90 
91     const struct option long_opts[] = {
92         {"input", required_argument, NULL, 'i'},
93         {"output", required_argument, NULL, 'o'},
94         {"blind", required_argument, NULL, 'b'},
95         {"save", required_argument, NULL, 's'},
96         {"help", no_argument, NULL, 'H'},
97         {0, 0, 0, 0},
98     };
99 
100     int opt = -1;
101     while ((opt = getopt_long (argc, argv, "", long_opts, NULL)) != -1)
102     {
103         switch (opt) {
104         case 'i':
105             file_in_name = optarg;
106             break;
107         case 'o':
108             file_out_name = optarg;
109             break;
110         case 'b':
111             blind = (strcasecmp (optarg, "false") == 0 ? false : true);
112             break;
113         case 's':
114             need_save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
115             break;
116         case 'H':
117             usage (argv[0]);
118             return -1;
119         default:
120             printf ("getopt_long return unknown value:%c\n", opt);
121             usage (argv[0]);
122             return -1;
123         }
124     }
125 
126     if (optind < argc || argc < 2)
127     {
128         printf ("unknown option %s\n", argv[optind]);
129         usage (argv[0]);
130         return -1;
131     }
132 
133     if (!file_in_name || !file_out_name)
134     {
135         XCAM_LOG_ERROR ("input/output path is NULL");
136         return -1;
137     }
138 
139     printf ("Description-----------\n");
140     printf ("input image file:%s\n", file_in_name);
141     printf ("output file :%s\n", file_out_name);
142     printf ("blind deblurring:%s\n", blind ? "true" : "false");
143     printf ("need save file:%s\n", need_save_output ? "true" : "false");
144     printf ("----------------------\n");
145 
146     SmartPtr<CVImageSharp> sharp = new CVImageSharp ();
147     cv::Mat input_image = cv::imread (file_in_name, CV_LOAD_IMAGE_COLOR);
148     cv::Mat output_image;
149     if (input_image.empty ())
150     {
151         XCAM_LOG_ERROR ("input file read error");
152         return 0;
153     }
154     if (blind)
155     {
156         blind_deblurring (input_image, output_image);
157     }
158     else
159     {
160         non_blind_deblurring (input_image, output_image);
161     }
162     float input_sharp = sharp->measure_sharp (input_image);
163     float output_sharp = sharp->measure_sharp (output_image);
164     if (need_save_output)
165     {
166         cv::imwrite (file_out_name, output_image);
167     }
168     XCAM_ASSERT (output_sharp > input_sharp);
169 }
170 
171