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