Merge pull request #1704 from SpecLad:merge-2.4
[profile/ivi/opencv.git] / samples / gpu / super_resolution.cpp
1 #include <iostream>
2 #include <iomanip>
3 #include <string>
4 #include "opencv2/core.hpp"
5 #include "opencv2/core/utility.hpp"
6 #include "opencv2/highgui.hpp"
7 #include "opencv2/imgproc.hpp"
8 #include "opencv2/contrib.hpp"
9 #include "opencv2/superres.hpp"
10 #include "opencv2/superres/optical_flow.hpp"
11 #include "opencv2/opencv_modules.hpp"
12
13 #if defined(HAVE_OPENCV_OCL)
14 #include "opencv2/ocl/ocl.hpp"
15 #endif
16
17 using namespace std;
18 using namespace cv;
19 using namespace cv::superres;
20 bool useOclChanged;
21 #define MEASURE_TIME(op) \
22     { \
23         TickMeter tm; \
24         tm.start(); \
25         op; \
26         tm.stop(); \
27         cout << tm.getTimeSec() << " sec" << endl; \
28     }
29
30 static Ptr<DenseOpticalFlowExt> createOptFlow(const string& name, bool useGpu)
31 {
32     if (name == "farneback")
33     {
34         if (useGpu)
35             return createOptFlow_Farneback_CUDA();
36         else
37             return createOptFlow_Farneback();
38     }
39     else if (name == "simple")
40         return createOptFlow_Simple();
41     else if (name == "tvl1")
42     {
43         if (useGpu)
44             return createOptFlow_DualTVL1_CUDA();
45         else
46             return createOptFlow_DualTVL1();
47     }
48     else if (name == "brox")
49         return createOptFlow_Brox_CUDA();
50     else if (name == "pyrlk")
51         return createOptFlow_PyrLK_CUDA();
52     else
53     {
54         cerr << "Incorrect Optical Flow algorithm - " << name << endl;
55     }
56     return Ptr<DenseOpticalFlowExt>();
57 }
58 #if defined(HAVE_OPENCV_OCL)
59 static Ptr<DenseOpticalFlowExt> createOptFlow(const string& name)
60 {
61     if (name == "farneback")
62     {
63         return createOptFlow_Farneback_OCL();
64     }
65     else if (name == "simple")
66     {
67         useOclChanged = true;
68         std::cout<<"simple on OpenCL has not been implemented. Use CPU instead!\n";
69         return createOptFlow_Simple();
70     }
71     else if (name == "tvl1")
72         return createOptFlow_DualTVL1_OCL();
73     else if (name == "brox")
74     {
75         std::cout<<"brox has not been implemented!\n";
76         return Ptr<DenseOpticalFlowExt>();
77     }
78     else if (name == "pyrlk")
79         return createOptFlow_PyrLK_OCL();
80     else
81     {
82         cerr << "Incorrect Optical Flow algorithm - " << name << endl;
83     }
84     return Ptr<DenseOpticalFlowExt>();
85 }
86 #endif
87 int main(int argc, const char* argv[])
88 {
89     useOclChanged = false;
90     CommandLineParser cmd(argc, argv,
91         "{ v video      |           | Input video }"
92         "{ o output     |           | Output video }"
93         "{ s scale      | 4         | Scale factor }"
94         "{ i iterations | 180       | Iteration count }"
95         "{ t temporal   | 4         | Radius of the temporal search area }"
96         "{ f flow       | farneback | Optical flow algorithm (farneback, simple, tvl1, brox, pyrlk) }"
97         "{ g            | false     | CPU as default device, cuda for CUDA and ocl for OpenCL }"
98         "{ h help       | false     | Print help message }"
99     );
100
101     if (cmd.get<bool>("help"))
102     {
103         cout << "This sample demonstrates Super Resolution algorithms for video sequence" << endl;
104         cmd.printMessage();
105         return 0;
106     }
107
108     const string inputVideoName = cmd.get<string>("video");
109     const string outputVideoName = cmd.get<string>("output");
110     const int scale = cmd.get<int>("scale");
111     const int iterations = cmd.get<int>("iterations");
112     const int temporalAreaRadius = cmd.get<int>("temporal");
113     const string optFlow = cmd.get<string>("flow");
114     string gpuOption = cmd.get<string>("gpu");
115
116     std::transform(gpuOption.begin(), gpuOption.end(), gpuOption.begin(), ::tolower);
117
118     bool useCuda = false;
119     bool useOcl = false;
120
121     if(gpuOption.compare("ocl") == 0)
122         useOcl = true;
123     else if(gpuOption.compare("cuda") == 0)
124         useCuda = true;
125
126 #ifndef HAVE_OPENCV_OCL
127     if(useOcl)
128     {
129         {
130             cout<<"OPENCL is not compiled\n";
131             return 0;
132         }
133     }
134 #endif
135 #if defined(HAVE_OPENCV_OCL)
136     if(useCuda)
137     {
138         CV_Assert(!useOcl);
139     }
140 #endif
141     Ptr<SuperResolution> superRes;
142
143
144 #if defined(HAVE_OPENCV_OCL)
145     if(useOcl)
146     {
147         Ptr<DenseOpticalFlowExt> of = createOptFlow(optFlow);
148         if (of.empty())
149             exit(-1);
150         if(useOclChanged)
151         {
152             superRes = createSuperResolution_BTVL1();
153             useOcl = !useOcl;
154         }else
155             superRes = createSuperResolution_BTVL1_OCL();
156         superRes->set("opticalFlow", of);
157     }
158     else
159 #endif
160     {
161         if (useCuda)
162             superRes = createSuperResolution_BTVL1_CUDA();
163         else
164             superRes = createSuperResolution_BTVL1();
165
166         Ptr<DenseOpticalFlowExt> of = createOptFlow(optFlow, useCuda);
167
168         if (of.empty())
169             exit(-1);
170         superRes->set("opticalFlow", of);
171     }
172
173     superRes->set("scale", scale);
174     superRes->set("iterations", iterations);
175     superRes->set("temporalAreaRadius", temporalAreaRadius);
176
177     Ptr<FrameSource> frameSource;
178     if (useCuda)
179     {
180         // Try to use gpu Video Decoding
181         try
182         {
183             frameSource = createFrameSource_Video_CUDA(inputVideoName);
184             Mat frame;
185             frameSource->nextFrame(frame);
186         }
187         catch (const cv::Exception&)
188         {
189             frameSource.release();
190         }
191     }
192     if (!frameSource)
193         frameSource = createFrameSource_Video(inputVideoName);
194
195     // skip first frame, it is usually corrupted
196     {
197         Mat frame;
198         frameSource->nextFrame(frame);
199         cout << "Input           : " << inputVideoName << " " << frame.size() << endl;
200         cout << "Scale factor    : " << scale << endl;
201         cout << "Iterations      : " << iterations << endl;
202         cout << "Temporal radius : " << temporalAreaRadius << endl;
203         cout << "Optical Flow    : " << optFlow << endl;
204 #if defined(HAVE_OPENCV_OCL)
205         cout << "Mode            : " << (useCuda ? "CUDA" : useOcl? "OpenCL" : "CPU") << endl;
206 #else
207         cout << "Mode            : " << (useCuda ? "CUDA" : "CPU") << endl;
208 #endif
209     }
210
211     superRes->setInput(frameSource);
212
213     VideoWriter writer;
214
215     for (int i = 0;; ++i)
216     {
217         cout << '[' << setw(3) << i << "] : ";
218         Mat result;
219
220 #if defined(HAVE_OPENCV_OCL)
221         cv::ocl::oclMat result_;
222
223         if(useOcl)
224         {
225             MEASURE_TIME(
226             {
227                 superRes->nextFrame(result_);
228                 ocl::finish();
229             });
230         }
231         else
232 #endif
233         {
234             MEASURE_TIME(superRes->nextFrame(result));
235         }
236
237 #ifdef HAVE_OPENCV_OCL
238         if(useOcl)
239         {
240             if(!result_.empty())
241             {
242                 result_.download(result);
243             }
244         }
245 #endif
246         if (result.empty())
247             break;
248
249         imshow("Super Resolution", result);
250
251         if (waitKey(1000) > 0)
252             break;
253
254         if (!outputVideoName.empty())
255         {
256             if (!writer.isOpened())
257                 writer.open(outputVideoName, VideoWriter::fourcc('X', 'V', 'I', 'D'), 25.0, result.size());
258             writer << result;
259         }
260     }
261
262     return 0;
263 }