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