Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/openvx/wrappers_video.cpp
16337 views
1
#include <iostream>
2
#include <stdexcept>
3
4
//wrappers
5
#include "ivx.hpp"
6
7
//OpenCV includes
8
#include "opencv2/core.hpp"
9
#include "opencv2/imgproc.hpp"
10
#include "opencv2/imgcodecs.hpp"
11
#include "opencv2/highgui.hpp"
12
13
enum UserMemoryMode
14
{
15
COPY, USER_MEM, MAP
16
};
17
18
ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage);
19
int ovxDemo(std::string inputPath, UserMemoryMode mode);
20
21
22
ivx::Graph createProcessingGraph(ivx::Image& inputImage, ivx::Image& outputImage)
23
{
24
using namespace ivx;
25
26
Context context = inputImage.get<Context>();
27
Graph graph = Graph::create(context);
28
29
vx_uint32 width = inputImage.width();
30
vx_uint32 height = inputImage.height();
31
32
// Intermediate images
33
Image
34
yuv = Image::createVirtual(graph, 0, 0, VX_DF_IMAGE_YUV4),
35
gray = Image::createVirtual(graph),
36
smoothed = Image::createVirtual(graph),
37
cannied = Image::createVirtual(graph),
38
halfImg = Image::create(context, width, height, VX_DF_IMAGE_U8),
39
halfCanny = Image::create(context, width, height, VX_DF_IMAGE_U8);
40
41
// Constants
42
vx_uint32 threshCannyMin = 127;
43
vx_uint32 threshCannyMax = 192;
44
Threshold threshCanny = Threshold::createRange(context, VX_TYPE_UINT8, threshCannyMin, threshCannyMax);
45
46
ivx::Scalar alpha = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, 0.5);
47
48
// Sequence of some image operations
49
Node::create(graph, VX_KERNEL_COLOR_CONVERT, inputImage, yuv);
50
Node::create(graph, VX_KERNEL_CHANNEL_EXTRACT, yuv,
51
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_CHANNEL_Y), gray);
52
//node can also be added in function-like style
53
nodes::gaussian3x3(graph, gray, smoothed);
54
Node::create(graph, VX_KERNEL_CANNY_EDGE_DETECTOR, smoothed, threshCanny,
55
ivx::Scalar::create<VX_TYPE_INT32>(context, 3),
56
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_NORM_L2), cannied);
57
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, gray, alpha, halfImg);
58
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, cannied, alpha, halfCanny);
59
Node::create(graph, VX_KERNEL_ADD, halfImg, halfCanny,
60
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_CONVERT_POLICY_SATURATE), outputImage);
61
62
graph.verify();
63
64
return graph;
65
}
66
67
68
int ovxDemo(std::string inputPath, UserMemoryMode mode)
69
{
70
using namespace cv;
71
using namespace ivx;
72
73
Mat frame;
74
VideoCapture vc(inputPath);
75
if (!vc.isOpened())
76
return -1;
77
78
vc >> frame;
79
if (frame.empty()) return -1;
80
81
//check frame format
82
if (frame.type() != CV_8UC3) return -1;
83
84
try
85
{
86
Context context = Context::create();
87
//put user data from cv::Mat to vx_image
88
vx_df_image color = Image::matTypeToFormat(frame.type());
89
vx_uint32 width = frame.cols, height = frame.rows;
90
Image ivxImage;
91
if (mode == COPY)
92
{
93
ivxImage = Image::create(context, width, height, color);
94
}
95
else
96
{
97
ivxImage = Image::createFromHandle(context, color, Image::createAddressing(frame), frame.data);
98
}
99
100
Image ivxResult;
101
102
Mat output;
103
if (mode == COPY || mode == MAP)
104
{
105
//we will copy or map data from vx_image to cv::Mat
106
ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
107
}
108
else // if (mode == MAP_TO_VX)
109
{
110
//create vx_image based on user data, no copying required
111
output = cv::Mat(height, width, CV_8U, cv::Scalar(0));
112
ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U),
113
Image::createAddressing(output), output.data);
114
}
115
116
Graph graph = createProcessingGraph(ivxImage, ivxResult);
117
118
bool stop = false;
119
while (!stop)
120
{
121
if (mode == COPY) ivxImage.copyFrom(0, frame);
122
123
// Graph execution
124
graph.process();
125
126
//getting resulting image in cv::Mat
127
Image::Patch resultPatch;
128
std::vector<void*> ptrs;
129
std::vector<void*> prevPtrs(ivxResult.planes());
130
if (mode == COPY)
131
{
132
ivxResult.copyTo(0, output);
133
}
134
else if (mode == MAP)
135
{
136
//create cv::Mat based on vx_image mapped data
137
resultPatch.map(ivxResult, 0, ivxResult.getValidRegion(), VX_READ_AND_WRITE);
138
//generally this is very bad idea!
139
//but in our case unmap() won't happen until output is in use
140
output = resultPatch.getMat();
141
}
142
else // if(mode == MAP_TO_VX)
143
{
144
#ifdef VX_VERSION_1_1
145
//we should take user memory back from vx_image before using it (even before reading)
146
ivxResult.swapHandle(ptrs, prevPtrs);
147
#endif
148
}
149
150
//here output goes
151
imshow("press q to quit", output);
152
if ((char)waitKey(1) == 'q') stop = true;
153
154
#ifdef VX_VERSION_1_1
155
//restore handle
156
if (mode == USER_MEM)
157
{
158
ivxResult.swapHandle(prevPtrs, ptrs);
159
}
160
#endif
161
162
//this line is unnecessary since unmapping is done on destruction of patch
163
//resultPatch.unmap();
164
165
//grab next frame
166
Mat temp = frame;
167
vc >> frame;
168
if (frame.empty()) stop = true;
169
if (mode != COPY && frame.data != temp.data)
170
{
171
//frame was reallocated, pointer to data changed
172
frame.copyTo(temp);
173
}
174
}
175
176
destroyAllWindows();
177
178
#ifdef VX_VERSION_1_1
179
if (mode != COPY)
180
{
181
//we should take user memory back before release
182
//(it's not done automatically according to standard)
183
ivxImage.swapHandle();
184
if (mode == USER_MEM) ivxResult.swapHandle();
185
}
186
#endif
187
}
188
catch (const ivx::RuntimeError& e)
189
{
190
std::cerr << "Error: code = " << e.status() << ", message = " << e.what() << std::endl;
191
return e.status();
192
}
193
catch (const ivx::WrapperError& e)
194
{
195
std::cerr << "Error: message = " << e.what() << std::endl;
196
return -1;
197
}
198
199
return 0;
200
}
201
202
203
int main(int argc, char *argv[])
204
{
205
const std::string keys =
206
"{help h usage ? | | }"
207
"{video | <none> | video file to be processed}"
208
"{mode | copy | user memory interaction mode: \n"
209
"copy: create VX images and copy data to/from them\n"
210
"user_mem: use handles to user-allocated memory\n"
211
"map: map resulting VX image to user memory}"
212
;
213
214
cv::CommandLineParser parser(argc, argv, keys);
215
parser.about("OpenVX interoperability sample demonstrating OpenVX wrappers usage."
216
"The application opens a video and processes it with OpenVX graph while outputting result in a window");
217
if (parser.has("help"))
218
{
219
parser.printMessage();
220
return 0;
221
}
222
std::string videoPath = parser.get<std::string>("video");
223
std::string modeString = parser.get<std::string>("mode");
224
UserMemoryMode mode;
225
if(modeString == "copy")
226
{
227
mode = COPY;
228
}
229
else if(modeString == "user_mem")
230
{
231
mode = USER_MEM;
232
}
233
else if(modeString == "map")
234
{
235
mode = MAP;
236
}
237
else
238
{
239
std::cerr << modeString << ": unknown memory mode" << std::endl;
240
return -1;
241
}
242
243
if (!parser.check())
244
{
245
parser.printErrors();
246
return -1;
247
}
248
249
return ovxDemo(videoPath, mode);
250
}
251
252