1 #include <iostream>
2 #include <iomanip>
3 #include <string>
4 #include <ctype.h>
5 
6 #include "opencv2/core.hpp"
7 #include "opencv2/core/utility.hpp"
8 #include "opencv2/highgui.hpp"
9 #include "opencv2/imgproc.hpp"
10 #include "opencv2/superres.hpp"
11 #include "opencv2/superres/optical_flow.hpp"
12 #include "opencv2/opencv_modules.hpp"
13 
14 using namespace std;
15 using namespace cv;
16 using namespace cv::superres;
17 
18 #define MEASURE_TIME(op) \
19     { \
20         TickMeter tm; \
21         tm.start(); \
22         op; \
23         tm.stop(); \
24         cout << tm.getTimeSec() << " sec" << endl; \
25     }
26 
createOptFlow(const string & name,bool useGpu)27 static Ptr<cv::superres::DenseOpticalFlowExt> createOptFlow(const string& name, bool useGpu)
28 {
29     if (name == "farneback")
30     {
31         if (useGpu)
32             return cv::superres::createOptFlow_Farneback_CUDA();
33         else
34             return cv::superres::createOptFlow_Farneback();
35     }
36     /*else if (name == "simple")
37         return createOptFlow_Simple();*/
38     else if (name == "tvl1")
39     {
40         if (useGpu)
41             return cv::superres::createOptFlow_DualTVL1_CUDA();
42         else
43             return cv::superres::createOptFlow_DualTVL1();
44     }
45     else if (name == "brox")
46         return cv::superres::createOptFlow_Brox_CUDA();
47     else if (name == "pyrlk")
48         return cv::superres::createOptFlow_PyrLK_CUDA();
49     else
50         cerr << "Incorrect Optical Flow algorithm - " << name << endl;
51 
52     return Ptr<cv::superres::DenseOpticalFlowExt>();
53 }
54 
main(int argc,const char * argv[])55 int main(int argc, const char* argv[])
56 {
57     CommandLineParser cmd(argc, argv,
58         "{ v video      |           | Input video (mandatory)}"
59         "{ o output     |           | Output video }"
60         "{ s scale      | 4         | Scale factor }"
61         "{ i iterations | 180       | Iteration count }"
62         "{ t temporal   | 4         | Radius of the temporal search area }"
63         "{ f flow       | farneback | Optical flow algorithm (farneback, tvl1, brox, pyrlk) }"
64         "{ g gpu        | false     | CPU as default device, cuda for CUDA }"
65         "{ h help       | false     | Print help message }"
66     );
67 
68     const string inputVideoName = cmd.get<string>("video");
69     if (cmd.get<bool>("help") || inputVideoName.empty())
70     {
71         cout << "This sample demonstrates Super Resolution algorithms for video sequence" << endl;
72         cmd.printMessage();
73         return EXIT_SUCCESS;
74     }
75 
76     const string outputVideoName = cmd.get<string>("output");
77     const int scale = cmd.get<int>("scale");
78     const int iterations = cmd.get<int>("iterations");
79     const int temporalAreaRadius = cmd.get<int>("temporal");
80     const string optFlow = cmd.get<string>("flow");
81     string gpuOption = cmd.get<string>("gpu");
82 
83     std::transform(gpuOption.begin(), gpuOption.end(), gpuOption.begin(), ::tolower);
84 
85     bool useCuda = gpuOption.compare("cuda") == 0;
86     Ptr<SuperResolution> superRes;
87 
88     if (useCuda)
89         superRes = createSuperResolution_BTVL1_CUDA();
90     else
91         superRes = createSuperResolution_BTVL1();
92 
93     Ptr<cv::superres::DenseOpticalFlowExt> of = createOptFlow(optFlow, useCuda);
94 
95     if (of.empty())
96         return EXIT_FAILURE;
97     superRes->setOpticalFlow(of);
98 
99     superRes->setScale(scale);
100     superRes->setIterations(iterations);
101     superRes->setTemporalAreaRadius(temporalAreaRadius);
102 
103     Ptr<FrameSource> frameSource;
104     if (useCuda)
105     {
106         // Try to use gpu Video Decoding
107         try
108         {
109             frameSource = createFrameSource_Video_CUDA(inputVideoName);
110             Mat frame;
111             frameSource->nextFrame(frame);
112         }
113         catch (const cv::Exception&)
114         {
115             frameSource.release();
116         }
117     }
118     if (!frameSource)
119         frameSource = createFrameSource_Video(inputVideoName);
120 
121     // skip first frame, it is usually corrupted
122     {
123         Mat frame;
124         frameSource->nextFrame(frame);
125         cout << "Input           : " << inputVideoName << " " << frame.size() << endl;
126         cout << "Scale factor    : " << scale << endl;
127         cout << "Iterations      : " << iterations << endl;
128         cout << "Temporal radius : " << temporalAreaRadius << endl;
129         cout << "Optical Flow    : " << optFlow << endl;
130         cout << "Mode            : " << (useCuda ? "CUDA" : "CPU") << endl;
131     }
132 
133     superRes->setInput(frameSource);
134 
135     VideoWriter writer;
136 
137     for (int i = 0;; ++i)
138     {
139         cout << '[' << setw(3) << i << "] : " << flush;
140         Mat result;
141 
142         MEASURE_TIME(superRes->nextFrame(result));
143 
144         if (result.empty())
145             break;
146 
147         imshow("Super Resolution", result);
148 
149         if (waitKey(1000) > 0)
150             break;
151 
152         if (!outputVideoName.empty())
153         {
154             if (!writer.isOpened())
155                 writer.open(outputVideoName, VideoWriter::fourcc('X', 'V', 'I', 'D'), 25.0, result.size());
156             writer << result;
157         }
158     }
159 
160     return 0;
161 }
162