Home | History | Annotate | Download | only in directx
      1 /*
      2 // Sample demonstrating interoperability of OpenCV UMat with Direct X surface
      3 // Base class for Direct X application
      4 */
      5 #include <string>
      6 #include <iostream>
      7 #include <queue>
      8 
      9 #include "opencv2/core.hpp"
     10 #include "opencv2/core/directx.hpp"
     11 #include "opencv2/core/ocl.hpp"
     12 #include "opencv2/imgproc.hpp"
     13 #include "opencv2/videoio.hpp"
     14 
     15 #include "winapp.hpp"
     16 
     17 #define SAFE_RELEASE(p) if (p) { p->Release(); p = NULL; }
     18 
     19 
     20 class D3DSample : public WinApp
     21 {
     22 public:
     23     enum MODE
     24     {
     25         MODE_NOP,
     26         MODE_CPU,
     27         MODE_GPU
     28     };
     29 
     30     D3DSample(int width, int height, std::string& window_name, cv::VideoCapture& cap) :
     31         WinApp(width, height, window_name)
     32     {
     33         m_shutdown          = false;
     34         m_mode              = MODE_NOP;
     35         m_modeStr[0]        = cv::String("No processing");
     36         m_modeStr[1]        = cv::String("Processing on CPU");
     37         m_modeStr[2]        = cv::String("Processing on GPU");
     38         m_disableProcessing = false;
     39         m_cap               = cap;
     40     }
     41 
     42     ~D3DSample() {}
     43 
     44     virtual int create() { return WinApp::create(); }
     45     virtual int render() = 0;
     46     virtual int cleanup()
     47     {
     48         m_shutdown = true;
     49         return WinApp::cleanup();
     50     }
     51 
     52     static float getFps()
     53     {
     54         static std::queue<int64> time_queue;
     55 
     56         int64 now = cv::getTickCount();
     57         int64 then = 0;
     58         time_queue.push(now);
     59 
     60         if (time_queue.size() >= 2)
     61             then = time_queue.front();
     62 
     63         if (time_queue.size() >= 25)
     64             time_queue.pop();
     65 
     66         size_t sz = time_queue.size();
     67 
     68         float fps = sz * (float)cv::getTickFrequency() / (now - then);
     69 
     70         return fps;
     71     }
     72 
     73 protected:
     74     virtual LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     75     {
     76         switch (message)
     77         {
     78         case WM_CHAR:
     79             if (wParam >= '0' && wParam <= '2')
     80             {
     81                 m_mode = static_cast<MODE>((char)wParam - '0');
     82                 return 0;
     83             }
     84             else if (wParam == VK_SPACE)
     85             {
     86                 m_disableProcessing = !m_disableProcessing;
     87                 return 0;
     88             }
     89             else if (wParam == VK_ESCAPE)
     90             {
     91                 return cleanup();
     92             }
     93             break;
     94 
     95         case WM_CLOSE:
     96             return cleanup();
     97 
     98         case WM_DESTROY:
     99             ::PostQuitMessage(0);
    100             return 0;
    101         }
    102 
    103         return ::DefWindowProc(hWnd, message, wParam, lParam);
    104     }
    105 
    106     // do render at idle
    107     virtual int idle() { return render(); }
    108 
    109 protected:
    110     bool               m_shutdown;
    111     bool               m_disableProcessing;
    112     MODE               m_mode;
    113     cv::String         m_modeStr[3];
    114     cv::VideoCapture   m_cap;
    115     cv::Mat            m_frame_bgr;
    116     cv::Mat            m_frame_rgba;
    117 };
    118 
    119 
    120 static void help()
    121 {
    122     printf(
    123         "\nSample demonstrating interoperability of DirectX and OpenCL with OpenCV.\n"
    124         "Hot keys: \n"
    125         "    0 - no processing\n"
    126         "    1 - blur DX surface on CPU through OpenCV\n"
    127         "    2 - blur DX surface on GPU through OpenCV using OpenCL\n"
    128         "  ESC - exit\n\n");
    129 }
    130 
    131 
    132 static const char* keys =
    133 {
    134     "{c camera | true  | use camera or not}"
    135     "{f file   |       | movie file name  }"
    136     "{h help   | false | print help info  }"
    137 };
    138 
    139 
    140 template <typename TApp>
    141 int d3d_app(int argc, char** argv, std::string& title)
    142 {
    143     cv::CommandLineParser parser(argc, argv, keys); \
    144     bool   useCamera = parser.has("camera"); \
    145     string file      = parser.get<string>("file"); \
    146     bool   showHelp  = parser.get<bool>("help"); \
    147 
    148     if (showHelp)
    149         help();
    150 
    151     parser.printMessage();
    152 
    153     cv::VideoCapture cap;
    154 
    155     if (useCamera)
    156         cap.open(0);
    157     else
    158         cap.open(file.c_str());
    159 
    160     if (!cap.isOpened())
    161     {
    162         printf("can not open camera or video file\n");
    163         return -1;
    164     }
    165 
    166     int width  = (int)cap.get(CAP_PROP_FRAME_WIDTH);
    167     int height = (int)cap.get(CAP_PROP_FRAME_HEIGHT);
    168 
    169     std::string wndname = title;
    170 
    171     TApp app(width, height, wndname, cap);
    172 
    173     try
    174     {
    175         app.create();
    176         return app.run();
    177     }
    178 
    179     catch (cv::Exception& e)
    180     {
    181         std::cerr << "Exception: " << e.what() << std::endl;
    182         return 10;
    183     }
    184 
    185     catch (...)
    186     {
    187         std::cerr << "FATAL ERROR: Unknown exception" << std::endl;
    188         return 11;
    189     }
    190 }
    191