Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/openvx/no_wrappers.cpp
16337 views
1
#include <iostream>
2
#include <stdexcept>
3
4
//OpenVX includes
5
#include <VX/vx.h>
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
#ifndef VX_VERSION_1_1
14
const vx_enum VX_IMAGE_FORMAT = VX_IMAGE_ATTRIBUTE_FORMAT;
15
const vx_enum VX_IMAGE_WIDTH = VX_IMAGE_ATTRIBUTE_WIDTH;
16
const vx_enum VX_IMAGE_HEIGHT = VX_IMAGE_ATTRIBUTE_HEIGHT;
17
const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST;
18
const vx_enum VX_MEMORY_TYPE_NONE = VX_IMPORT_TYPE_NONE;
19
const vx_enum VX_THRESHOLD_THRESHOLD_VALUE = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_VALUE;
20
const vx_enum VX_THRESHOLD_THRESHOLD_LOWER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_LOWER;
21
const vx_enum VX_THRESHOLD_THRESHOLD_UPPER = VX_THRESHOLD_ATTRIBUTE_THRESHOLD_UPPER;
22
typedef uintptr_t vx_map_id;
23
#endif
24
25
enum UserMemoryMode
26
{
27
COPY, USER_MEM
28
};
29
30
vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy);
31
cv::Mat copyVxImageToCvMat(vx_image ovxImage);
32
void swapVxImage(vx_image ovxImage);
33
vx_status createProcessingGraph(vx_image inputImage, vx_image outputImage, vx_graph& graph);
34
int ovxDemo(std::string inputPath, UserMemoryMode mode);
35
36
37
vx_image convertCvMatToVxImage(vx_context context, cv::Mat image, bool toCopy)
38
{
39
if (!(!image.empty() && image.dims <= 2 && image.channels() == 1))
40
throw std::runtime_error("Invalid format");
41
42
vx_uint32 width = image.cols;
43
vx_uint32 height = image.rows;
44
45
vx_df_image color;
46
switch (image.depth())
47
{
48
case CV_8U:
49
color = VX_DF_IMAGE_U8;
50
break;
51
case CV_16U:
52
color = VX_DF_IMAGE_U16;
53
break;
54
case CV_16S:
55
color = VX_DF_IMAGE_S16;
56
break;
57
case CV_32S:
58
color = VX_DF_IMAGE_S32;
59
break;
60
default:
61
throw std::runtime_error("Invalid format");
62
break;
63
}
64
65
vx_imagepatch_addressing_t addr;
66
addr.dim_x = width;
67
addr.dim_y = height;
68
addr.stride_x = (vx_uint32)image.elemSize();
69
addr.stride_y = (vx_uint32)image.step.p[0];
70
vx_uint8* ovxData = image.data;
71
72
vx_image ovxImage;
73
if (toCopy)
74
{
75
ovxImage = vxCreateImage(context, width, height, color);
76
if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS)
77
throw std::runtime_error("Failed to create image");
78
vx_rectangle_t rect;
79
80
vx_status status = vxGetValidRegionImage(ovxImage, &rect);
81
if (status != VX_SUCCESS)
82
throw std::runtime_error("Failed to get valid region");
83
84
#ifdef VX_VERSION_1_1
85
status = vxCopyImagePatch(ovxImage, &rect, 0, &addr, ovxData, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);
86
if (status != VX_SUCCESS)
87
throw std::runtime_error("Failed to copy image patch");
88
#else
89
status = vxAccessImagePatch(ovxImage, &rect, 0, &addr, (void**)&ovxData, VX_WRITE_ONLY);
90
if (status != VX_SUCCESS)
91
throw std::runtime_error("Failed to access image patch");
92
status = vxCommitImagePatch(ovxImage, &rect, 0, &addr, ovxData);
93
if (status != VX_SUCCESS)
94
throw std::runtime_error("Failed to commit image patch");
95
#endif
96
}
97
else
98
{
99
ovxImage = vxCreateImageFromHandle(context, color, &addr, (void**)&ovxData, VX_MEMORY_TYPE_HOST);
100
if (vxGetStatus((vx_reference)ovxImage) != VX_SUCCESS)
101
throw std::runtime_error("Failed to create image from handle");
102
}
103
104
return ovxImage;
105
}
106
107
108
cv::Mat copyVxImageToCvMat(vx_image ovxImage)
109
{
110
vx_status status;
111
vx_df_image df_image = 0;
112
vx_uint32 width, height;
113
status = vxQueryImage(ovxImage, VX_IMAGE_FORMAT, &df_image, sizeof(vx_df_image));
114
if (status != VX_SUCCESS)
115
throw std::runtime_error("Failed to query image");
116
status = vxQueryImage(ovxImage, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
117
if (status != VX_SUCCESS)
118
throw std::runtime_error("Failed to query image");
119
status = vxQueryImage(ovxImage, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
120
if (status != VX_SUCCESS)
121
throw std::runtime_error("Failed to query image");
122
123
if (!(width > 0 && height > 0)) throw std::runtime_error("Invalid format");
124
125
int depth;
126
switch (df_image)
127
{
128
case VX_DF_IMAGE_U8:
129
depth = CV_8U;
130
break;
131
case VX_DF_IMAGE_U16:
132
depth = CV_16U;
133
break;
134
case VX_DF_IMAGE_S16:
135
depth = CV_16S;
136
break;
137
case VX_DF_IMAGE_S32:
138
depth = CV_32S;
139
break;
140
default:
141
throw std::runtime_error("Invalid format");
142
break;
143
}
144
145
cv::Mat image(height, width, CV_MAKE_TYPE(depth, 1));
146
147
vx_rectangle_t rect;
148
rect.start_x = rect.start_y = 0;
149
rect.end_x = width; rect.end_y = height;
150
151
vx_imagepatch_addressing_t addr;
152
addr.dim_x = width;
153
addr.dim_y = height;
154
addr.stride_x = (vx_uint32)image.elemSize();
155
addr.stride_y = (vx_uint32)image.step.p[0];
156
vx_uint8* matData = image.data;
157
158
#ifdef VX_VERSION_1_1
159
status = vxCopyImagePatch(ovxImage, &rect, 0, &addr, matData, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);
160
if (status != VX_SUCCESS)
161
throw std::runtime_error("Failed to copy image patch");
162
#else
163
status = vxAccessImagePatch(ovxImage, &rect, 0, &addr, (void**)&matData, VX_READ_ONLY);
164
if (status != VX_SUCCESS)
165
throw std::runtime_error("Failed to access image patch");
166
status = vxCommitImagePatch(ovxImage, &rect, 0, &addr, matData);
167
if (status != VX_SUCCESS)
168
throw std::runtime_error("Failed to commit image patch");
169
#endif
170
171
return image;
172
}
173
174
175
void swapVxImage(vx_image ovxImage)
176
{
177
#ifdef VX_VERSION_1_1
178
vx_status status;
179
vx_memory_type_e memType;
180
status = vxQueryImage(ovxImage, VX_IMAGE_MEMORY_TYPE, &memType, sizeof(vx_memory_type_e));
181
if (status != VX_SUCCESS)
182
throw std::runtime_error("Failed to query image");
183
if (memType == VX_MEMORY_TYPE_NONE)
184
{
185
//was created by copying user data
186
throw std::runtime_error("Image wasn't created from user handle");
187
}
188
else
189
{
190
//was created from user handle
191
status = vxSwapImageHandle(ovxImage, NULL, NULL, 0);
192
if (status != VX_SUCCESS)
193
throw std::runtime_error("Failed to swap image handle");
194
}
195
#else
196
//not supported until OpenVX 1.1
197
(void) ovxImage;
198
#endif
199
}
200
201
202
vx_status createProcessingGraph(vx_image inputImage, vx_image outputImage, vx_graph& graph)
203
{
204
vx_status status;
205
vx_context context = vxGetContext((vx_reference)inputImage);
206
status = vxGetStatus((vx_reference)context);
207
if(status != VX_SUCCESS) return status;
208
209
graph = vxCreateGraph(context);
210
status = vxGetStatus((vx_reference)graph);
211
if (status != VX_SUCCESS) return status;
212
213
vx_uint32 width, height;
214
status = vxQueryImage(inputImage, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
215
if (status != VX_SUCCESS) return status;
216
status = vxQueryImage(inputImage, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
217
if (status != VX_SUCCESS) return status;
218
219
// Intermediate images
220
vx_image
221
smoothed = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT),
222
cannied = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT),
223
halfImg = vxCreateImage(context, width, height, VX_DF_IMAGE_U8),
224
halfCanny = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
225
226
vx_image virtualImages[] = {smoothed, cannied, halfImg, halfCanny};
227
for(size_t i = 0; i < sizeof(virtualImages)/sizeof(vx_image); i++)
228
{
229
status = vxGetStatus((vx_reference)virtualImages[i]);
230
if (status != VX_SUCCESS) return status;
231
}
232
233
// Constants
234
vx_uint32 threshValue = 50;
235
vx_threshold thresh = vxCreateThreshold(context, VX_THRESHOLD_TYPE_BINARY, VX_TYPE_UINT8);
236
vxSetThresholdAttribute(thresh, VX_THRESHOLD_THRESHOLD_VALUE,
237
&threshValue, sizeof(threshValue));
238
239
vx_uint32 threshCannyMin = 127;
240
vx_uint32 threshCannyMax = 192;
241
vx_threshold threshCanny = vxCreateThreshold(context, VX_THRESHOLD_TYPE_RANGE, VX_TYPE_UINT8);
242
vxSetThresholdAttribute(threshCanny, VX_THRESHOLD_THRESHOLD_LOWER, &threshCannyMin,
243
sizeof(threshCannyMin));
244
vxSetThresholdAttribute(threshCanny, VX_THRESHOLD_THRESHOLD_UPPER, &threshCannyMax,
245
sizeof(threshCannyMax));
246
vx_float32 alphaValue = 0.5;
247
vx_scalar alpha = vxCreateScalar(context, VX_TYPE_FLOAT32, &alphaValue);
248
249
// Sequence of meaningless image operations
250
vx_node nodes[] = {
251
vxGaussian3x3Node(graph, inputImage, smoothed),
252
vxCannyEdgeDetectorNode(graph, smoothed, threshCanny, 3, VX_NORM_L2, cannied),
253
vxAccumulateWeightedImageNode(graph, inputImage, alpha, halfImg),
254
vxAccumulateWeightedImageNode(graph, cannied, alpha, halfCanny),
255
vxAddNode(graph, halfImg, halfCanny, VX_CONVERT_POLICY_SATURATE, outputImage)
256
};
257
258
for (size_t i = 0; i < sizeof(nodes) / sizeof(vx_node); i++)
259
{
260
status = vxGetStatus((vx_reference)nodes[i]);
261
if (status != VX_SUCCESS) return status;
262
}
263
264
status = vxVerifyGraph(graph);
265
return status;
266
}
267
268
269
int ovxDemo(std::string inputPath, UserMemoryMode mode)
270
{
271
cv::Mat image = cv::imread(inputPath, cv::IMREAD_GRAYSCALE);
272
if (image.empty()) return -1;
273
274
//check image format
275
if (image.depth() != CV_8U || image.channels() != 1) return -1;
276
277
vx_status status;
278
vx_context context = vxCreateContext();
279
status = vxGetStatus((vx_reference)context);
280
if (status != VX_SUCCESS) return status;
281
282
//put user data from cv::Mat to vx_image
283
vx_image ovxImage;
284
ovxImage = convertCvMatToVxImage(context, image, mode == COPY);
285
286
vx_uint32 width = image.cols, height = image.rows;
287
288
vx_image ovxResult;
289
cv::Mat output;
290
if (mode == COPY)
291
{
292
//we will copy data from vx_image to cv::Mat
293
ovxResult = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
294
if (vxGetStatus((vx_reference)ovxResult) != VX_SUCCESS)
295
throw std::runtime_error("Failed to create image");
296
}
297
else
298
{
299
//create vx_image based on user data, no copying required
300
output = cv::Mat(height, width, CV_8U, cv::Scalar(0));
301
ovxResult = convertCvMatToVxImage(context, output, false);
302
}
303
304
vx_graph graph;
305
status = createProcessingGraph(ovxImage, ovxResult, graph);
306
if (status != VX_SUCCESS) return status;
307
308
// Graph execution
309
status = vxProcessGraph(graph);
310
if (status != VX_SUCCESS) return status;
311
312
//getting resulting image in cv::Mat
313
if (mode == COPY)
314
{
315
output = copyVxImageToCvMat(ovxResult);
316
}
317
else
318
{
319
//we should take user memory back from vx_image before using it (even before reading)
320
swapVxImage(ovxResult);
321
}
322
323
//here output goes
324
cv::imshow("processing result", output);
325
cv::waitKey(0);
326
327
//we need to take user memory back before releasing the image
328
if (mode == USER_MEM)
329
swapVxImage(ovxImage);
330
331
cv::destroyAllWindows();
332
333
status = vxReleaseContext(&context);
334
return status;
335
}
336
337
338
int main(int argc, char *argv[])
339
{
340
const std::string keys =
341
"{help h usage ? | | }"
342
"{image | <none> | image to be processed}"
343
"{mode | copy | user memory interaction mode: \n"
344
"copy: create VX images and copy data to/from them\n"
345
"user_mem: use handles to user-allocated memory}"
346
;
347
348
cv::CommandLineParser parser(argc, argv, keys);
349
parser.about("OpenVX interoperability sample demonstrating standard OpenVX API."
350
"The application loads an image, processes it with OpenVX graph and outputs result in a window");
351
if (parser.has("help"))
352
{
353
parser.printMessage();
354
return 0;
355
}
356
std::string imgPath = parser.get<std::string>("image");
357
std::string modeString = parser.get<std::string>("mode");
358
UserMemoryMode mode;
359
if(modeString == "copy")
360
{
361
mode = COPY;
362
}
363
else if(modeString == "user_mem")
364
{
365
mode = USER_MEM;
366
}
367
else if(modeString == "map")
368
{
369
std::cerr << modeString << " is not implemented in this sample" << std::endl;
370
return -1;
371
}
372
else
373
{
374
std::cerr << modeString << ": unknown memory mode" << std::endl;
375
return -1;
376
}
377
378
if (!parser.check())
379
{
380
parser.printErrors();
381
return -1;
382
}
383
384
return ovxDemo(imgPath, mode);
385
}
386
387