Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/openvx/wrappers.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
smoothed = Image::createVirtual(graph),
35
cannied = Image::createVirtual(graph),
36
halfImg = Image::create(context, width, height, VX_DF_IMAGE_U8),
37
halfCanny = Image::create(context, width, height, VX_DF_IMAGE_U8);
38
39
// Constants
40
vx_uint32 threshCannyMin = 127;
41
vx_uint32 threshCannyMax = 192;
42
Threshold threshCanny = Threshold::createRange(context, VX_TYPE_UINT8, threshCannyMin, threshCannyMax);
43
44
ivx::Scalar alpha = ivx::Scalar::create<VX_TYPE_FLOAT32>(context, 0.5);
45
46
// Sequence of some image operations
47
// Node can also be added in function-like style
48
nodes::gaussian3x3(graph, inputImage, smoothed);
49
Node::create(graph, VX_KERNEL_CANNY_EDGE_DETECTOR, smoothed, threshCanny,
50
ivx::Scalar::create<VX_TYPE_INT32>(context, 3),
51
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_NORM_L2), cannied);
52
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, inputImage, alpha, halfImg);
53
Node::create(graph, VX_KERNEL_ACCUMULATE_WEIGHTED, cannied, alpha, halfCanny);
54
Node::create(graph, VX_KERNEL_ADD, halfImg, halfCanny,
55
ivx::Scalar::create<VX_TYPE_ENUM>(context, VX_CONVERT_POLICY_SATURATE), outputImage);
56
57
graph.verify();
58
59
return graph;
60
}
61
62
63
int ovxDemo(std::string inputPath, UserMemoryMode mode)
64
{
65
using namespace cv;
66
using namespace ivx;
67
68
Mat image = imread(inputPath, IMREAD_GRAYSCALE);
69
if (image.empty()) return -1;
70
71
//check image format
72
if (image.depth() != CV_8U || image.channels() != 1) return -1;
73
74
try
75
{
76
Context context = Context::create();
77
//put user data from cv::Mat to vx_image
78
vx_df_image color = Image::matTypeToFormat(image.type());
79
vx_uint32 width = image.cols, height = image.rows;
80
Image ivxImage;
81
if (mode == COPY)
82
{
83
ivxImage = Image::create(context, width, height, color);
84
ivxImage.copyFrom(0, image);
85
}
86
else
87
{
88
ivxImage = Image::createFromHandle(context, color, Image::createAddressing(image), image.data);
89
}
90
91
Image ivxResult;
92
Image::Patch resultPatch;
93
Mat output;
94
if (mode == COPY || mode == MAP)
95
{
96
//we will copy or map data from vx_image to cv::Mat
97
ivxResult = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
98
}
99
else // if (mode == MAP_TO_VX)
100
{
101
//create vx_image based on user data, no copying required
102
output = cv::Mat(height, width, CV_8U, cv::Scalar(0));
103
ivxResult = Image::createFromHandle(context, Image::matTypeToFormat(CV_8U),
104
Image::createAddressing(output), output.data);
105
}
106
107
Graph graph = createProcessingGraph(ivxImage, ivxResult);
108
109
// Graph execution
110
graph.process();
111
112
//getting resulting image in cv::Mat
113
if (mode == COPY)
114
{
115
ivxResult.copyTo(0, output);
116
}
117
else if (mode == MAP)
118
{
119
//create cv::Mat based on vx_image mapped data
120
resultPatch.map(ivxResult, 0, ivxResult.getValidRegion());
121
//generally this is very bad idea!
122
//but in our case unmap() won't happen until output is in use
123
output = resultPatch.getMat();
124
}
125
else // if (mode == MAP_TO_VX)
126
{
127
#ifdef VX_VERSION_1_1
128
//we should take user memory back from vx_image before using it (even before reading)
129
ivxResult.swapHandle();
130
#endif
131
}
132
133
//here output goes
134
cv::imshow("processing result", output);
135
cv::waitKey(0);
136
137
cv::destroyAllWindows();
138
139
#ifdef VX_VERSION_1_1
140
if (mode != COPY)
141
{
142
//we should take user memory back before release
143
//(it's not done automatically according to standard)
144
ivxImage.swapHandle();
145
if (mode == USER_MEM) ivxResult.swapHandle();
146
}
147
#endif
148
149
//the line is unnecessary since unmapping is done on destruction of patch
150
//resultPatch.unmap();
151
}
152
catch (const ivx::RuntimeError& e)
153
{
154
std::cerr << "Error: code = " << e.status() << ", message = " << e.what() << std::endl;
155
return e.status();
156
}
157
catch (const ivx::WrapperError& e)
158
{
159
std::cerr << "Error: message = " << e.what() << std::endl;
160
return -1;
161
}
162
163
return 0;
164
}
165
166
167
int main(int argc, char *argv[])
168
{
169
const std::string keys =
170
"{help h usage ? | | }"
171
"{image | <none> | image to be processed}"
172
"{mode | copy | user memory interaction mode: \n"
173
"copy: create VX images and copy data to/from them\n"
174
"user_mem: use handles to user-allocated memory\n"
175
"map: map resulting VX image to user memory}"
176
;
177
178
cv::CommandLineParser parser(argc, argv, keys);
179
parser.about("OpenVX interoperability sample demonstrating OpenVX wrappers usage."
180
"The application loads an image, processes it with OpenVX graph and outputs result in a window");
181
if (parser.has("help"))
182
{
183
parser.printMessage();
184
return 0;
185
}
186
std::string imgPath = parser.get<std::string>("image");
187
std::string modeString = parser.get<std::string>("mode");
188
UserMemoryMode mode;
189
if(modeString == "copy")
190
{
191
mode = COPY;
192
}
193
else if(modeString == "user_mem")
194
{
195
mode = USER_MEM;
196
}
197
else if(modeString == "map")
198
{
199
mode = MAP;
200
}
201
else
202
{
203
std::cerr << modeString << ": unknown memory mode" << std::endl;
204
return -1;
205
}
206
207
if (!parser.check())
208
{
209
parser.printErrors();
210
return -1;
211
}
212
213
return ovxDemo(imgPath, mode);
214
}
215
216