Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/gapi/test/gapi_sample_pipelines.cpp
16337 views
1
// This file is part of OpenCV project.
2
// It is subject to the license terms in the LICENSE file found in the top-level directory
3
// of this distribution and at http://opencv.org/license.html.
4
//
5
// Copyright (C) 2018 Intel Corporation
6
7
8
#include "test_precomp.hpp"
9
10
#include <stdexcept>
11
#include <ade/util/iota_range.hpp>
12
#include "logger.hpp"
13
14
namespace opencv_test
15
{
16
17
namespace
18
{
19
G_TYPED_KERNEL(GInvalidResize, <GMat(GMat,Size,double,double,int)>, "org.opencv.test.invalid_resize")
20
{
21
static GMatDesc outMeta(GMatDesc in, Size, double, double, int) { return in; }
22
};
23
24
GAPI_OCV_KERNEL(GOCVInvalidResize, GInvalidResize)
25
{
26
static void run(const cv::Mat& in, cv::Size sz, double fx, double fy, int interp, cv::Mat &out)
27
{
28
cv::resize(in, out, sz, fx, fy, interp);
29
}
30
};
31
32
G_TYPED_KERNEL(GReallocatingCopy, <GMat(GMat)>, "org.opencv.test.reallocating_copy")
33
{
34
static GMatDesc outMeta(GMatDesc in) { return in; }
35
};
36
37
GAPI_OCV_KERNEL(GOCVReallocatingCopy, GReallocatingCopy)
38
{
39
static void run(const cv::Mat& in, cv::Mat &out)
40
{
41
out = in.clone();
42
}
43
};
44
}
45
46
TEST(GAPI_Pipeline, OverloadUnary_MatMat)
47
{
48
cv::GMat in;
49
cv::GComputation comp(in, cv::gapi::bitwise_not(in));
50
51
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
52
cv::Mat ref_mat = ~in_mat;
53
54
cv::Mat out_mat;
55
comp.apply(in_mat, out_mat);
56
EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));
57
58
out_mat = cv::Mat();
59
auto cc = comp.compile(cv::descr_of(in_mat));
60
cc(in_mat, out_mat);
61
EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));
62
}
63
64
TEST(GAPI_Pipeline, OverloadUnary_MatScalar)
65
{
66
cv::GMat in;
67
cv::GComputation comp(in, cv::gapi::sum(in));
68
69
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
70
cv::Scalar ref_scl = cv::sum(in_mat);
71
72
cv::Scalar out_scl;
73
comp.apply(in_mat, out_scl);
74
EXPECT_EQ(out_scl, ref_scl);
75
76
out_scl = cv::Scalar();
77
auto cc = comp.compile(cv::descr_of(in_mat));
78
cc(in_mat, out_scl);
79
EXPECT_EQ(out_scl, ref_scl);
80
}
81
82
TEST(GAPI_Pipeline, OverloadBinary_Mat)
83
{
84
cv::GMat a, b;
85
cv::GComputation comp(a, b, cv::gapi::add(a, b));
86
87
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
88
cv::Mat ref_mat = (in_mat+in_mat);
89
90
cv::Mat out_mat;
91
comp.apply(in_mat, in_mat, out_mat);
92
EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));
93
94
out_mat = cv::Mat();
95
auto cc = comp.compile(cv::descr_of(in_mat), cv::descr_of(in_mat));
96
cc(in_mat, in_mat, out_mat);
97
EXPECT_EQ(0, cv::countNonZero(out_mat != ref_mat));
98
}
99
100
TEST(GAPI_Pipeline, OverloadBinary_Scalar)
101
{
102
cv::GMat a, b;
103
cv::GComputation comp(a, b, cv::gapi::sum(a + b));
104
105
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
106
cv::Scalar ref_scl = cv::sum(in_mat+in_mat);
107
108
cv::Scalar out_scl;
109
comp.apply(in_mat, in_mat, out_scl);
110
EXPECT_EQ(out_scl, ref_scl);
111
112
out_scl = cv::Scalar();
113
auto cc = comp.compile(cv::descr_of(in_mat), cv::descr_of(in_mat));
114
cc(in_mat, in_mat, out_scl);
115
EXPECT_EQ(out_scl, ref_scl);
116
}
117
118
TEST(GAPI_Pipeline, Sharpen)
119
{
120
const cv::Size sz_in (1280, 720);
121
const cv::Size sz_out( 640, 480);
122
cv::Mat in_mat (sz_in, CV_8UC3);
123
in_mat = cv::Scalar(128, 33, 53);
124
125
cv::Mat out_mat(sz_out, CV_8UC3);
126
cv::Mat out_mat_y;
127
cv::Mat out_mat_ocv(sz_out, CV_8UC3);
128
129
float sharpen_coeffs[] = {
130
0.0f, -1.f, 0.0f,
131
-1.0f, 5.f, -1.0f,
132
0.0f, -1.f, 0.0f
133
};
134
cv::Mat sharpen_kernel(3, 3, CV_32F, sharpen_coeffs);
135
136
// G-API code //////////////////////////////////////////////////////////////
137
138
cv::GMat in;
139
auto vga = cv::gapi::resize(in, sz_out);
140
auto yuv = cv::gapi::RGB2YUV(vga);
141
auto yuv_p = cv::gapi::split3(yuv);
142
auto y_sharp = cv::gapi::filter2D(std::get<0>(yuv_p), -1, sharpen_kernel);
143
auto yuv_new = cv::gapi::merge3(y_sharp, std::get<1>(yuv_p), std::get<2>(yuv_p));
144
auto out = cv::gapi::YUV2RGB(yuv_new);
145
146
cv::GComputation c(cv::GIn(in), cv::GOut(y_sharp, out));
147
c.apply(cv::gin(in_mat), cv::gout(out_mat_y, out_mat));
148
149
// OpenCV code /////////////////////////////////////////////////////////////
150
{
151
cv::Mat smaller;
152
cv::resize(in_mat, smaller, sz_out);
153
154
cv::Mat yuv_mat;
155
cv::cvtColor(smaller, yuv_mat, cv::COLOR_RGB2YUV);
156
std::vector<cv::Mat> yuv_planar(3);
157
cv::split(yuv_mat, yuv_planar);
158
cv::filter2D(yuv_planar[0], yuv_planar[0], -1, sharpen_kernel);
159
cv::merge(yuv_planar, yuv_mat);
160
cv::cvtColor(yuv_mat, out_mat_ocv, cv::COLOR_YUV2RGB);
161
}
162
163
// Comparison //////////////////////////////////////////////////////////////
164
{
165
cv::Mat diff = out_mat_ocv != out_mat;
166
std::vector<cv::Mat> diffBGR(3);
167
cv::split(diff, diffBGR);
168
EXPECT_EQ(0, cv::countNonZero(diffBGR[0]));
169
EXPECT_EQ(0, cv::countNonZero(diffBGR[1]));
170
EXPECT_EQ(0, cv::countNonZero(diffBGR[2]));
171
}
172
173
// Metadata check /////////////////////////////////////////////////////////
174
{
175
auto cc = c.compile(cv::descr_of(in_mat));
176
auto metas = cc.outMetas();
177
ASSERT_EQ(2u, metas.size());
178
179
auto out_y_meta = cv::util::get<cv::GMatDesc>(metas[0]);
180
auto out_meta = cv::util::get<cv::GMatDesc>(metas[1]);
181
182
// Y-output
183
EXPECT_EQ(CV_8U, out_y_meta.depth);
184
EXPECT_EQ(1, out_y_meta.chan);
185
EXPECT_EQ(640, out_y_meta.size.width);
186
EXPECT_EQ(480, out_y_meta.size.height);
187
188
// Final output
189
EXPECT_EQ(CV_8U, out_meta.depth);
190
EXPECT_EQ(3, out_meta.chan);
191
EXPECT_EQ(640, out_meta.size.width);
192
EXPECT_EQ(480, out_meta.size.height);
193
}
194
}
195
196
TEST(GAPI_Pipeline, CustomRGB2YUV)
197
{
198
const cv::Size sz(1280, 720);
199
200
// BEWARE:
201
//
202
// std::vector<cv::Mat> out_mats_cv(3, cv::Mat(sz, CV_8U))
203
//
204
// creates a vector of 3 elements pointing to the same Mat!
205
// FIXME: Make a G-API check for that
206
const int INS = 3;
207
std::vector<cv::Mat> in_mats(INS);
208
for (auto i : ade::util::iota(INS))
209
{
210
in_mats[i].create(sz, CV_8U);
211
cv::randu(in_mats[i], cv::Scalar::all(0), cv::Scalar::all(255));
212
}
213
214
const int OUTS = 3;
215
std::vector<cv::Mat> out_mats_cv(OUTS);
216
std::vector<cv::Mat> out_mats_gapi(OUTS);
217
for (auto i : ade::util::iota(OUTS))
218
{
219
out_mats_cv [i].create(sz, CV_8U);
220
out_mats_gapi[i].create(sz, CV_8U);
221
}
222
223
// G-API code //////////////////////////////////////////////////////////////
224
{
225
cv::GMat r, g, b;
226
cv::GMat y = 0.299f*r + 0.587f*g + 0.114f*b;
227
cv::GMat u = 0.492f*(b - y);
228
cv::GMat v = 0.877f*(r - y);
229
230
cv::GComputation customCvt({r, g, b}, {y, u, v});
231
customCvt.apply(in_mats, out_mats_gapi);
232
}
233
234
// OpenCV code /////////////////////////////////////////////////////////////
235
{
236
cv::Mat r = in_mats[0], g = in_mats[1], b = in_mats[2];
237
cv::Mat y = 0.299f*r + 0.587f*g + 0.114f*b;
238
cv::Mat u = 0.492f*(b - y);
239
cv::Mat v = 0.877f*(r - y);
240
241
out_mats_cv[0] = y;
242
out_mats_cv[1] = u;
243
out_mats_cv[2] = v;
244
}
245
246
// Comparison //////////////////////////////////////////////////////////////
247
{
248
const auto diff = [](cv::Mat m1, cv::Mat m2, int t) {
249
return cv::abs(m1-m2) > t;
250
};
251
252
// FIXME: Not bit-accurate even now!
253
cv::Mat
254
diff_y = diff(out_mats_cv[0], out_mats_gapi[0], 2),
255
diff_u = diff(out_mats_cv[1], out_mats_gapi[1], 2),
256
diff_v = diff(out_mats_cv[2], out_mats_gapi[2], 2);
257
258
EXPECT_EQ(0, cv::countNonZero(diff_y));
259
EXPECT_EQ(0, cv::countNonZero(diff_u));
260
EXPECT_EQ(0, cv::countNonZero(diff_v));
261
}
262
}
263
264
TEST(GAPI_Pipeline, PipelineWithInvalidKernel)
265
{
266
cv::GMat in, out;
267
cv::Mat in_mat(500, 500, CV_8UC1), out_mat;
268
out = GInvalidResize::on(in, cv::Size(300, 300), 0.0, 0.0, cv::INTER_LINEAR);
269
270
const auto pkg = cv::gapi::kernels<GOCVInvalidResize>();
271
cv::GComputation comp(cv::GIn(in), cv::GOut(out));
272
273
EXPECT_THROW(comp.apply(in_mat, out_mat, cv::compile_args(pkg)), std::logic_error);
274
}
275
276
TEST(GAPI_Pipeline, InvalidOutputComputation)
277
{
278
cv::GMat in1, out1, out2, out3;
279
280
std::tie(out1, out2, out2) = cv::gapi::split3(in1);
281
cv::GComputation c({in1}, {out1, out2, out3});
282
cv::Mat in_mat;
283
cv::Mat out_mat1, out_mat2, out_mat3, out_mat4;
284
std::vector<cv::Mat> u_outs = {out_mat1, out_mat2, out_mat3, out_mat4};
285
std::vector<cv::Mat> u_ins = {in_mat};
286
287
EXPECT_THROW(c.apply(u_ins, u_outs), std::logic_error);
288
}
289
290
TEST(GAPI_Pipeline, PipelineAllocatingKernel)
291
{
292
cv::GMat in, out;
293
cv::Mat in_mat(500, 500, CV_8UC1), out_mat;
294
out = GReallocatingCopy::on(in);
295
296
const auto pkg = cv::gapi::kernels<GOCVReallocatingCopy>();
297
cv::GComputation comp(cv::GIn(in), cv::GOut(out));
298
299
EXPECT_THROW(comp.apply(in_mat, out_mat, cv::compile_args(pkg)), std::logic_error);
300
}
301
} // namespace opencv_test
302
303