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