Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/gapi/test/gapi_fluid_resize_test.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 "gapi_fluid_test_kernels.hpp"
11
12
namespace opencv_test
13
{
14
15
using namespace cv::gapi_test_kernels;
16
17
G_TYPED_KERNEL(TCopy, <GMat(GMat)>, "test.fluid.copy")
18
{
19
static GMatDesc outMeta(const cv::GMatDesc &in) {
20
return in;
21
}
22
};
23
24
GAPI_FLUID_KERNEL(FCopy, TCopy, false)
25
{
26
static const int Window = 1;
27
28
static void run(const cv::gapi::fluid::View &in,
29
cv::gapi::fluid::Buffer &out)
30
{
31
const uint8_t* in_row = in .InLine <uint8_t>(0);
32
uint8_t* out_row = out.OutLine<uint8_t>();
33
34
for (int i = 0, w = in.length(); i < w; i++)
35
{
36
//std::cout << std::setw(4) << int(in_row[i]);
37
out_row[i] = in_row[i];
38
}
39
//std::cout << std::endl;
40
}
41
};
42
43
GAPI_FLUID_KERNEL(FResizeNN1Lpi, cv::gapi::core::GResize, false)
44
{
45
static const int Window = 1;
46
static const auto Kind = GFluidKernel::Kind::Resize;
47
48
static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,
49
cv::gapi::fluid::Buffer& out)
50
51
{
52
auto length = out.length();
53
double vRatio = (double)in.meta().size.height / out.meta().size.height;
54
double hRatio = (double)in.length() / length;
55
auto y = out.y();
56
auto inY = in.y();
57
58
for (int l = 0; l < out.lpi(); l++)
59
{
60
auto sy = static_cast<int>((y+l) * vRatio);
61
int idx = sy - inY;
62
63
const auto src = in.InLine <unsigned char>(idx);
64
auto dst = out.OutLine<unsigned char>(l);
65
66
for (int x = 0; x < length; x++)
67
{
68
auto inX = static_cast<int>(x * hRatio);
69
dst[x] = src[inX];
70
}
71
}
72
}
73
};
74
75
namespace
76
{
77
namespace func
78
{
79
template <class Mapper>
80
void initScratch(const cv::GMatDesc& in, cv::Size outSz, cv::gapi::fluid::Buffer &scratch)
81
{
82
CV_Assert(in.depth == CV_8U && in.chan == 1);
83
84
cv::Size scratch_size{static_cast<int>(outSz.width * sizeof(typename Mapper::Unit)), 1};
85
86
cv::GMatDesc desc;
87
desc.chan = 1;
88
desc.depth = CV_8UC1;
89
desc.size = scratch_size;
90
91
cv::gapi::fluid::Buffer buffer(desc);
92
scratch = std::move(buffer);
93
94
auto mapX = scratch.OutLine<typename Mapper::Unit>();
95
double hRatio = (double)in.size.width / outSz.width;
96
97
for (int x = 0, w = outSz.width; x < w; x++)
98
{
99
mapX[x] = Mapper::map(hRatio, 0, in.size.width, x);
100
}
101
}
102
103
template <class Mapper>
104
inline void calcRow(const cv::gapi::fluid::View& in, cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)
105
{
106
double vRatio = (double)in.meta().size.height / out.meta().size.height;
107
auto mapX = scratch.OutLine<typename Mapper::Unit>();
108
auto inY = in.y();
109
auto inH = in.meta().size.height;
110
auto outY = out.y();
111
auto length = out.length();
112
113
for (int l = 0; l < out.lpi(); l++)
114
{
115
auto mapY = Mapper::map(vRatio, inY, inH, outY + l);
116
117
const auto src0 = in.InLine <unsigned char>(mapY.s0);
118
const auto src1 = in.InLine <unsigned char>(mapY.s1);
119
120
auto dst = out.OutLine<unsigned char>(l);
121
122
for (int x = 0; x < length; x++)
123
{
124
auto alpha0 = mapX[x].alpha0;
125
auto alpha1 = mapX[x].alpha1;
126
auto sx0 = mapX[x].s0;
127
auto sx1 = mapX[x].s1;
128
129
int res0 = src0[sx0]*alpha0 + src0[sx1]*alpha1;
130
int res1 = src1[sx0]*alpha0 + src1[sx1]*alpha1;
131
132
dst[x] = uchar(( ((mapY.alpha0 * (res0 >> 4)) >> 16) + ((mapY.alpha1 * (res1 >> 4)) >> 16) + 2)>>2);
133
}
134
}
135
}
136
} // namespace func
137
138
constexpr static const int INTER_RESIZE_COEF_BITS = 11;
139
constexpr static const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;
140
141
namespace linear
142
{
143
struct Mapper
144
{
145
struct Unit
146
{
147
short alpha0;
148
short alpha1;
149
int s0;
150
int s1;
151
};
152
153
static inline Unit map(double ratio, int start, int max, int outCoord)
154
{
155
auto f = static_cast<float>((outCoord + 0.5f) * ratio - 0.5f);
156
int s = cvFloor(f);
157
f -= s;
158
159
Unit u;
160
161
u.s0 = std::max(s - start, 0);
162
u.s1 = ((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1;
163
164
u.alpha0 = saturate_cast<short>((1.0f - f) * INTER_RESIZE_COEF_SCALE);
165
u.alpha1 = saturate_cast<short>((f) * INTER_RESIZE_COEF_SCALE);
166
167
return u;
168
}
169
};
170
171
} // namespace linear
172
173
namespace areaUpscale
174
{
175
struct Mapper
176
{
177
struct Unit
178
{
179
short alpha0;
180
short alpha1;
181
int s0;
182
int s1;
183
};
184
185
static inline Unit map(double ratio, int start, int max, int outCoord)
186
{
187
int s = cvFloor(outCoord*ratio);
188
float f = (float)((outCoord+1) - (s+1)/ratio);
189
f = f <= 0 ? 0.f : f - cvFloor(f);
190
191
Unit u;
192
193
u.s0 = std::max(s - start, 0);
194
u.s1 = ((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1;
195
196
u.alpha0 = saturate_cast<short>((1.0f - f) * INTER_RESIZE_COEF_SCALE);
197
u.alpha1 = saturate_cast<short>((f) * INTER_RESIZE_COEF_SCALE);
198
199
return u;
200
}
201
};
202
} // namespace areaUpscale
203
} // anonymous namespace
204
205
GAPI_FLUID_KERNEL(FResizeLinear1Lpi, cv::gapi::core::GResize, true)
206
{
207
static const int Window = 1;
208
static const auto Kind = GFluidKernel::Kind::Resize;
209
210
static void initScratch(const cv::GMatDesc& in,
211
cv::Size outSz, double /*fx*/, double /*fy*/, int /*interp*/,
212
cv::gapi::fluid::Buffer &scratch)
213
{
214
func::initScratch<linear::Mapper>(in, outSz, scratch);
215
}
216
217
static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)
218
{}
219
220
static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,
221
cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)
222
223
{
224
func::calcRow<linear::Mapper>(in, out, scratch);
225
}
226
};
227
228
namespace
229
{
230
// FIXME
231
// Move to some common place (to reuse/align with ResizeAgent)
232
auto startInCoord = [](int outCoord, double ratio) {
233
return static_cast<int>(outCoord * ratio + 1e-3);
234
};
235
auto endInCoord = [](int outCoord, double ratio) {
236
return static_cast<int>(std::ceil((outCoord + 1) * ratio - 1e-3));
237
};
238
} // namespace
239
240
GAPI_FLUID_KERNEL(FResizeArea1Lpi, cv::gapi::core::GResize, false)
241
{
242
static const int Window = 1;
243
static const auto Kind = GFluidKernel::Kind::Resize;
244
245
static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,
246
cv::gapi::fluid::Buffer& out)
247
248
{
249
auto firstOutLineIdx = out.y();
250
auto firstViewLineIdx = in.y();
251
auto length = out.length();
252
double vRatio = (double)in.meta().size.height / out.meta().size.height;
253
double hRatio = (double)in.length() / length;
254
255
for (int l = 0; l < out.lpi(); l++)
256
{
257
int outY = firstOutLineIdx + l;
258
int startY = startInCoord(outY, vRatio);
259
int endY = endInCoord (outY, vRatio);
260
261
auto dst = out.OutLine<unsigned char>(l);
262
263
for (int x = 0; x < length; x++)
264
{
265
float res = 0.0;
266
267
int startX = startInCoord(x, hRatio);
268
int endX = endInCoord (x, hRatio);
269
270
for (int inY = startY; inY < endY; inY++)
271
{
272
double startCoordY = inY / vRatio;
273
double endCoordY = startCoordY + 1/vRatio;
274
275
if (startCoordY < outY) startCoordY = outY;
276
if (endCoordY > outY + 1) endCoordY = outY + 1;
277
278
float fracY = static_cast<float>((inY == startY || inY == endY - 1) ? endCoordY - startCoordY : 1/vRatio);
279
280
const auto src = in.InLine <unsigned char>(inY - firstViewLineIdx);
281
282
float rowSum = 0.0f;
283
284
for (int inX = startX; inX < endX; inX++)
285
{
286
double startCoordX = inX / hRatio;
287
double endCoordX = startCoordX + 1/hRatio;
288
289
if (startCoordX < x) startCoordX = x;
290
if (endCoordX > x + 1) endCoordX = x + 1;
291
292
float fracX = static_cast<float>((inX == startX || inX == endX - 1) ? endCoordX - startCoordX : 1/hRatio);
293
294
rowSum += src[inX] * fracX;
295
}
296
res += rowSum * fracY;
297
}
298
dst[x] = static_cast<unsigned char>(std::rint(res));
299
}
300
}
301
}
302
};
303
304
GAPI_FLUID_KERNEL(FResizeAreaUpscale1Lpi, cv::gapi::core::GResize, true)
305
{
306
static const int Window = 1;
307
static const auto Kind = GFluidKernel::Kind::Resize;
308
309
static void initScratch(const cv::GMatDesc& in,
310
cv::Size outSz, double /*fx*/, double /*fy*/, int /*interp*/,
311
cv::gapi::fluid::Buffer &scratch)
312
{
313
func::initScratch<areaUpscale::Mapper>(in, outSz, scratch);
314
}
315
316
static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)
317
{}
318
319
static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,
320
cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)
321
{
322
func::calcRow<areaUpscale::Mapper>(in, out, scratch);
323
}
324
};
325
326
#define ADD_RESIZE_KERNEL_WITH_LPI(interp, lpi, scratch) \
327
struct Resize##interp##lpi##LpiHelper : public FResize##interp##1Lpi { static const int LPI = lpi; }; \
328
struct FResize##interp##lpi##Lpi : public cv::GFluidKernelImpl<Resize##interp##lpi##LpiHelper, cv::gapi::core::GResize, scratch>{};
329
330
ADD_RESIZE_KERNEL_WITH_LPI(NN, 2, false)
331
ADD_RESIZE_KERNEL_WITH_LPI(NN, 3, false)
332
ADD_RESIZE_KERNEL_WITH_LPI(NN, 4, false)
333
334
ADD_RESIZE_KERNEL_WITH_LPI(Linear, 2, true)
335
ADD_RESIZE_KERNEL_WITH_LPI(Linear, 3, true)
336
ADD_RESIZE_KERNEL_WITH_LPI(Linear, 4, true)
337
338
ADD_RESIZE_KERNEL_WITH_LPI(Area, 2, false)
339
ADD_RESIZE_KERNEL_WITH_LPI(Area, 3, false)
340
ADD_RESIZE_KERNEL_WITH_LPI(Area, 4, false)
341
342
ADD_RESIZE_KERNEL_WITH_LPI(AreaUpscale, 2, true)
343
ADD_RESIZE_KERNEL_WITH_LPI(AreaUpscale, 3, true)
344
ADD_RESIZE_KERNEL_WITH_LPI(AreaUpscale, 4, true)
345
#undef ADD_RESIZE_KERNEL_WITH_LPI
346
347
static auto fluidResizeTestPackage = [](int interpolation, cv::Size szIn, cv::Size szOut, int lpi = 1)
348
{
349
using namespace cv;
350
using namespace cv::gapi;
351
bool upscale = szIn.width < szOut.width || szIn.height < szOut.height;
352
353
#define RESIZE_CASE(interp, lpi) \
354
case lpi: pkg = kernels<FCopy, FResize##interp##lpi##Lpi>(); break;
355
356
#define RESIZE_SWITCH(interp) \
357
switch(lpi) \
358
{ \
359
RESIZE_CASE(interp, 1) \
360
RESIZE_CASE(interp, 2) \
361
RESIZE_CASE(interp, 3) \
362
RESIZE_CASE(interp, 4) \
363
default: CV_Assert(false); \
364
}
365
366
GKernelPackage pkg;
367
switch (interpolation)
368
{
369
case INTER_NEAREST: RESIZE_SWITCH(NN); break;
370
case INTER_LINEAR: RESIZE_SWITCH(Linear); break;
371
case INTER_AREA:
372
{
373
if (upscale)
374
{
375
RESIZE_SWITCH(AreaUpscale)
376
}
377
else
378
{
379
RESIZE_SWITCH(Area);
380
}
381
}break;
382
default: CV_Assert(false);
383
}
384
return combine(pkg, fluidTestPackage, unite_policy::KEEP);
385
386
#undef RESIZE_SWITCH
387
#undef RESIZE_CASE
388
};
389
390
struct ResizeTestFluid : public TestWithParam<std::tuple<int, int, cv::Size, std::tuple<cv::Size, cv::Rect>, int, double>> {};
391
TEST_P(ResizeTestFluid, SanityTest)
392
{
393
int type = 0, interp = 0;
394
cv::Size sz_in, sz_out;
395
int lpi = 0;
396
double tolerance = 0.0;
397
cv::Rect outRoi;
398
std::tuple<cv::Size, cv::Rect> outSizeAndRoi;
399
std::tie(type, interp, sz_in, outSizeAndRoi, lpi, tolerance) = GetParam();
400
std::tie(sz_out, outRoi) = outSizeAndRoi;
401
if (outRoi == cv::Rect{}) outRoi = {0,0,sz_out.width,sz_out.height};
402
if (outRoi.width == 0) outRoi.width = sz_out.width;
403
double fx = 0, fy = 0;
404
405
cv::Mat in_mat1 (sz_in, type );
406
cv::Scalar mean = cv::Scalar(127);
407
cv::Scalar stddev = cv::Scalar(40.f);
408
409
cv::randn(in_mat1, mean, stddev);
410
411
cv::Mat out_mat = cv::Mat::zeros(sz_out, type);
412
cv::Mat out_mat_ocv = cv::Mat::zeros(sz_out, type);
413
414
cv::GMat in;
415
auto mid = TBlur3x3::on(in, cv::BORDER_REPLICATE, {});
416
auto out = cv::gapi::resize(mid, sz_out, fx, fy, interp);
417
418
cv::GComputation c(in, out);
419
c.apply(in_mat1, out_mat, cv::compile_args(GFluidOutputRois{{outRoi}}, fluidResizeTestPackage(interp, sz_in, sz_out, lpi)));
420
421
cv::Mat mid_mat;
422
cv::blur(in_mat1, mid_mat, {3,3}, {-1,-1}, cv::BORDER_REPLICATE);
423
cv::resize(mid_mat, out_mat_ocv, sz_out, fx, fy, interp);
424
425
cv::Mat absDiff;
426
cv::absdiff(out_mat(outRoi), out_mat_ocv(outRoi), absDiff);
427
EXPECT_EQ(0, cv::countNonZero(absDiff > tolerance));
428
}
429
430
INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeTestFluid,
431
Combine(Values(CV_8UC1),
432
Values(cv::INTER_NEAREST, cv::INTER_LINEAR),
433
Values(cv::Size(8, 7),
434
cv::Size(8, 8),
435
cv::Size(8, 64),
436
cv::Size(8, 25),
437
cv::Size(16, 8),
438
cv::Size(16, 7)),
439
Values(std::make_tuple(cv::Size(5, 4), cv::Rect{}),
440
std::make_tuple(cv::Size(5, 4), cv::Rect{0, 0, 0, 2}),
441
std::make_tuple(cv::Size(5, 4), cv::Rect{0, 1, 0, 2}),
442
std::make_tuple(cv::Size(5, 4), cv::Rect{0, 2, 0, 2}),
443
std::make_tuple(cv::Size(7, 7), cv::Rect{}),
444
std::make_tuple(cv::Size(7, 7), cv::Rect{0, 0, 0, 3}),
445
std::make_tuple(cv::Size(7, 7), cv::Rect{0, 2, 0, 2}),
446
std::make_tuple(cv::Size(7, 7), cv::Rect{0, 4, 0, 3}),
447
std::make_tuple(cv::Size(8, 4), cv::Rect{}),
448
std::make_tuple(cv::Size(8, 4), cv::Rect{0, 0, 0, 3}),
449
std::make_tuple(cv::Size(8, 4), cv::Rect{0, 1, 0, 2}),
450
std::make_tuple(cv::Size(8, 4), cv::Rect{0, 3, 0, 1})),
451
Values(1, 2, 3, 4), // lpi
452
Values(0.0)));
453
454
INSTANTIATE_TEST_CASE_P(ResizeAreaTestCPU, ResizeTestFluid,
455
Combine(Values(CV_8UC1),
456
Values(cv::INTER_AREA),
457
Values(cv::Size(8, 7),
458
cv::Size(8, 8),
459
cv::Size(8, 64),
460
cv::Size(8, 25),
461
cv::Size(16, 8),
462
cv::Size(16, 7)),
463
Values(std::make_tuple(cv::Size(5, 4), cv::Rect{}),
464
std::make_tuple(cv::Size(5, 4), cv::Rect{0, 0, 0, 2}),
465
std::make_tuple(cv::Size(5, 4), cv::Rect{0, 1, 0, 2}),
466
std::make_tuple(cv::Size(5, 4), cv::Rect{0, 2, 0, 2}),
467
std::make_tuple(cv::Size(7, 7), cv::Rect{}),
468
std::make_tuple(cv::Size(7, 7), cv::Rect{0, 0, 0, 3}),
469
std::make_tuple(cv::Size(7, 7), cv::Rect{0, 2, 0, 2}),
470
std::make_tuple(cv::Size(7, 7), cv::Rect{0, 4, 0, 3}),
471
std::make_tuple(cv::Size(8, 4), cv::Rect{}),
472
std::make_tuple(cv::Size(8, 4), cv::Rect{0, 0, 0, 3}),
473
std::make_tuple(cv::Size(8, 4), cv::Rect{0, 1, 0, 2}),
474
std::make_tuple(cv::Size(8, 4), cv::Rect{0, 3, 0, 1})),
475
Values(1, 2, 3, 4), // lpi
476
// Actually this tolerance only for cases where OpenCV
477
// uses ResizeAreaFast
478
Values(1.0)));
479
480
INSTANTIATE_TEST_CASE_P(ResizeUpscaleTestCPU, ResizeTestFluid,
481
Combine(Values(CV_8UC1),
482
Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
483
Values(cv::Size(1, 5),
484
cv::Size(3, 5),
485
cv::Size(7, 5),
486
cv::Size(1, 7),
487
cv::Size(3, 7),
488
cv::Size(7, 7)),
489
Values(std::make_tuple(cv::Size(8, 8), cv::Rect{0,0,8,2}),
490
std::make_tuple(cv::Size(8, 8), cv::Rect{0,2,8,2}),
491
std::make_tuple(cv::Size(8, 8), cv::Rect{0,4,8,2}),
492
std::make_tuple(cv::Size(8, 8), cv::Rect{0,6,8,2}),
493
std::make_tuple(cv::Size(8, 8), cv::Rect{0,0,8,8}),
494
std::make_tuple(cv::Size(16, 8), cv::Rect{}),
495
std::make_tuple(cv::Size(16, 64), cv::Rect{0, 0,16,16}),
496
std::make_tuple(cv::Size(16, 64), cv::Rect{0,16,16,16}),
497
std::make_tuple(cv::Size(16, 64), cv::Rect{0,32,16,16}),
498
std::make_tuple(cv::Size(16, 64), cv::Rect{0,48,16,16}),
499
std::make_tuple(cv::Size(16, 64), cv::Rect{0, 0,16,64}),
500
std::make_tuple(cv::Size(16, 25), cv::Rect{0, 0,16, 7}),
501
std::make_tuple(cv::Size(16, 25), cv::Rect{0, 7,16, 6}),
502
std::make_tuple(cv::Size(16, 25), cv::Rect{0,13,16, 6}),
503
std::make_tuple(cv::Size(16, 25), cv::Rect{0,19,16, 6}),
504
std::make_tuple(cv::Size(16, 25), cv::Rect{0, 0,16, 7}),
505
std::make_tuple(cv::Size(16, 25), cv::Rect{0, 7,16, 7}),
506
std::make_tuple(cv::Size(16, 25), cv::Rect{0,14,16, 7}),
507
std::make_tuple(cv::Size(16, 25), cv::Rect{0,21,16, 4}),
508
std::make_tuple(cv::Size(16, 25), cv::Rect{0, 0,16,25}),
509
std::make_tuple(cv::Size(16, 7), cv::Rect{}),
510
std::make_tuple(cv::Size(16, 8), cv::Rect{})),
511
Values(1, 2, 3, 4), // lpi
512
Values(0.0)));
513
514
INSTANTIATE_TEST_CASE_P(ResizeUpscaleOneDimDownscaleAnother, ResizeTestFluid,
515
Combine(Values(CV_8UC1),
516
Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
517
Values(cv::Size(6, 6),
518
cv::Size(8, 7),
519
cv::Size(8, 8),
520
cv::Size(8, 10),
521
cv::Size(10, 8),
522
cv::Size(10, 7)),
523
Values(std::make_tuple(cv::Size(11, 5), cv::Rect{}),
524
std::make_tuple(cv::Size(11, 5), cv::Rect{0, 0, 0, 2}),
525
std::make_tuple(cv::Size(11, 5), cv::Rect{0, 2, 0, 2}),
526
std::make_tuple(cv::Size(11, 5), cv::Rect{0, 4, 0, 1}),
527
std::make_tuple(cv::Size(12, 2), cv::Rect{}),
528
std::make_tuple(cv::Size(12, 2), cv::Rect{0, 0, 0, 1}),
529
std::make_tuple(cv::Size(12, 2), cv::Rect{0, 1, 0, 1}),
530
std::make_tuple(cv::Size(23, 3), cv::Rect{}),
531
std::make_tuple(cv::Size(23, 3), cv::Rect{0, 0, 0, 1}),
532
std::make_tuple(cv::Size(23, 3), cv::Rect{0, 1, 0, 1}),
533
std::make_tuple(cv::Size(23, 3), cv::Rect{0, 2, 0, 1}),
534
std::make_tuple(cv::Size(3, 24), cv::Rect{}),
535
std::make_tuple(cv::Size(3, 24), cv::Rect{0, 0, 0, 6}),
536
std::make_tuple(cv::Size(3, 24), cv::Rect{0, 6, 0, 6}),
537
std::make_tuple(cv::Size(3, 24), cv::Rect{0, 12, 0, 6}),
538
std::make_tuple(cv::Size(3, 24), cv::Rect{0, 18, 0, 6}),
539
std::make_tuple(cv::Size(5, 11), cv::Rect{}),
540
std::make_tuple(cv::Size(5, 11), cv::Rect{0, 0, 0, 3}),
541
std::make_tuple(cv::Size(5, 11), cv::Rect{0, 3, 0, 3}),
542
std::make_tuple(cv::Size(5, 11), cv::Rect{0, 6, 0, 3}),
543
std::make_tuple(cv::Size(5, 11), cv::Rect{0, 9, 0, 2})),
544
Values(1, 2, 3, 4), // lpi
545
Values(0.0)));
546
547
INSTANTIATE_TEST_CASE_P(Resize400_384TestCPU, ResizeTestFluid,
548
Combine(Values(CV_8UC1),
549
Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
550
Values(cv::Size(128, 400)),
551
Values(std::make_tuple(cv::Size(128, 384), cv::Rect{})),
552
Values(1, 2, 3, 4), // lpi
553
Values(0.0)));
554
555
INSTANTIATE_TEST_CASE_P(Resize220_400TestCPU, ResizeTestFluid,
556
Combine(Values(CV_8UC1),
557
Values(cv::INTER_LINEAR),
558
Values(cv::Size(220, 220)),
559
Values(std::make_tuple(cv::Size(400, 400), cv::Rect{})),
560
Values(1, 2, 3, 4), // lpi
561
Values(0.0)));
562
563
static auto cvBlur = [](const cv::Mat& in, cv::Mat& out, int kernelSize)
564
{
565
if (kernelSize == 1)
566
{
567
out = in;
568
}
569
else
570
{
571
cv::blur(in, out, {kernelSize, kernelSize});
572
}
573
};
574
575
using SizesWithRois = std::tuple<cv::Size, cv::Rect, cv::Size, cv::Rect>;
576
struct ResizeAndAnotherReaderTest : public TestWithParam<std::tuple<int, int, bool, SizesWithRois>>{};
577
TEST_P(ResizeAndAnotherReaderTest, SanityTest)
578
{
579
bool readFromInput = false;
580
int interp = -1, kernelSize = -1;
581
SizesWithRois sizesWithRois;
582
std::tie(interp, kernelSize, readFromInput, sizesWithRois) = GetParam();
583
584
cv::Size sz, resizedSz;
585
cv::Rect roi, resizedRoi;
586
std::tie(sz, roi, resizedSz, resizedRoi) = sizesWithRois;
587
588
cv::Mat in_mat(sz, CV_8UC1);
589
cv::Scalar mean = cv::Scalar(127);
590
cv::Scalar stddev = cv::Scalar(40.f);
591
cv::randn(in_mat, mean, stddev);
592
593
cv::Mat gapi_resize_out = cv::Mat::zeros(resizedSz, CV_8UC1);
594
cv::Mat gapi_blur_out = cv::Mat::zeros(sz, CV_8UC1);
595
596
auto blur = kernelSize == 1 ? &TBlur1x1::on : kernelSize == 3 ? &TBlur3x3::on : &TBlur5x5::on;
597
598
cv::GMat in, resize_out, blur_out;
599
600
if (readFromInput)
601
{
602
resize_out = gapi::resize(in, resizedSz, 0, 0, interp);
603
blur_out = blur(in, cv::BORDER_DEFAULT, {});
604
}
605
else
606
{
607
auto mid = TCopy::on(in);
608
resize_out = gapi::resize(mid, resizedSz, 0, 0, interp);
609
blur_out = blur(mid, cv::BORDER_DEFAULT, {});
610
}
611
612
cv::GComputation c(GIn(in), GOut(resize_out, blur_out));
613
c.apply(gin(in_mat), gout(gapi_resize_out, gapi_blur_out), cv::compile_args(GFluidOutputRois{{resizedRoi, roi}},
614
fluidResizeTestPackage(interp, sz, resizedSz)));
615
616
cv::Mat ocv_resize_out = cv::Mat::zeros(resizedSz, CV_8UC1);
617
cv::resize(in_mat, ocv_resize_out, resizedSz, 0, 0, interp);
618
cv::Mat ocv_blur_out = cv::Mat::zeros(sz, CV_8UC1);
619
cvBlur(in_mat, ocv_blur_out, kernelSize);
620
621
EXPECT_EQ(0, cv::countNonZero(gapi_resize_out(resizedRoi) != ocv_resize_out(resizedRoi)));
622
EXPECT_EQ(0, cv::countNonZero(gapi_blur_out(roi) != ocv_blur_out(roi)));
623
}
624
625
INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeAndAnotherReaderTest,
626
Combine(Values(cv::INTER_NEAREST, cv::INTER_LINEAR),
627
Values(1, 3, 5),
628
testing::Bool(), // Read from input directly or place a copy node at start
629
Values(std::make_tuple(cv::Size{8,8}, cv::Rect{0,0,8,8},
630
cv::Size{4,4}, cv::Rect{0,0,4,4}),
631
std::make_tuple(cv::Size{8,8}, cv::Rect{0,0,8,2},
632
cv::Size{4,4}, cv::Rect{0,0,4,1}),
633
std::make_tuple(cv::Size{8,8}, cv::Rect{0,2,8,4},
634
cv::Size{4,4}, cv::Rect{0,1,4,2}),
635
std::make_tuple(cv::Size{8,8}, cv::Rect{0,4,8,4},
636
cv::Size{4,4}, cv::Rect{0,2,4,2}),
637
std::make_tuple(cv::Size{64,64}, cv::Rect{0, 0,64,64},
638
cv::Size{49,49}, cv::Rect{0, 0,49,49}),
639
std::make_tuple(cv::Size{64,64}, cv::Rect{0, 0,64,15},
640
cv::Size{49,49}, cv::Rect{0, 0,49,11}),
641
std::make_tuple(cv::Size{64,64}, cv::Rect{0,11,64,23},
642
cv::Size{49,49}, cv::Rect{0, 9,49,17}),
643
std::make_tuple(cv::Size{64,64}, cv::Rect{0,50,64,14},
644
cv::Size{49,49}, cv::Rect{0,39,49,10}))));
645
646
struct BlursAfterResizeTest : public TestWithParam<std::tuple<int, int, int, bool, std::tuple<cv::Size, cv::Size, cv::Rect>>>{};
647
TEST_P(BlursAfterResizeTest, SanityTest)
648
{
649
bool readFromInput = false;
650
int interp = -1, kernelSize1 = -1, kernelSize2 = -1;
651
std::tuple<cv::Size, cv::Size, cv::Rect> sizesWithRoi;
652
std::tie(interp, kernelSize1, kernelSize2, readFromInput, sizesWithRoi) = GetParam();
653
654
cv::Size inSz, outSz;
655
cv::Rect outRoi;
656
std::tie(inSz, outSz, outRoi) = sizesWithRoi;
657
658
cv::Mat in_mat(inSz, CV_8UC1);
659
cv::Scalar mean = cv::Scalar(127);
660
cv::Scalar stddev = cv::Scalar(40.f);
661
cv::randn(in_mat, mean, stddev);
662
cv::Mat gapi_out1 = cv::Mat::zeros(outSz, CV_8UC1);
663
cv::Mat gapi_out2 = cv::Mat::zeros(outSz, CV_8UC1);
664
665
auto blur1 = kernelSize1 == 1 ? &TBlur1x1::on : kernelSize1 == 3 ? &TBlur3x3::on : &TBlur5x5::on;
666
auto blur2 = kernelSize2 == 1 ? &TBlur1x1::on : kernelSize2 == 3 ? &TBlur3x3::on : &TBlur5x5::on;
667
668
cv::GMat in, out1, out2;
669
if (readFromInput)
670
{
671
auto resized = gapi::resize(in, outSz, 0, 0, interp);
672
out1 = blur1(resized, cv::BORDER_DEFAULT, {});
673
out2 = blur2(resized, cv::BORDER_DEFAULT, {});
674
}
675
else
676
{
677
auto mid = TCopy::on(in);
678
auto resized = gapi::resize(mid, outSz, 0, 0, interp);
679
out1 = blur1(resized, cv::BORDER_DEFAULT, {});
680
out2 = blur2(resized, cv::BORDER_DEFAULT, {});
681
}
682
683
cv::GComputation c(GIn(in), GOut(out1, out2));
684
c.apply(gin(in_mat), gout(gapi_out1, gapi_out2), cv::compile_args(GFluidOutputRois{{outRoi, outRoi}},
685
fluidResizeTestPackage(interp, inSz, outSz)));
686
687
cv::Mat ocv_out1 = cv::Mat::zeros(outSz, CV_8UC1);
688
cv::Mat ocv_out2 = cv::Mat::zeros(outSz, CV_8UC1);
689
cv::Mat resized = cv::Mat::zeros(outSz, CV_8UC1);
690
cv::resize(in_mat, resized, outSz, 0, 0, interp);
691
cvBlur(resized, ocv_out1, kernelSize1);
692
cvBlur(resized, ocv_out2, kernelSize2);
693
694
EXPECT_EQ(0, cv::countNonZero(gapi_out1(outRoi) != ocv_out1(outRoi)));
695
EXPECT_EQ(0, cv::countNonZero(gapi_out2(outRoi) != ocv_out2(outRoi)));
696
}
697
698
INSTANTIATE_TEST_CASE_P(ResizeTestCPU, BlursAfterResizeTest,
699
Combine(Values(cv::INTER_NEAREST, cv::INTER_LINEAR),
700
Values(1, 3, 5),
701
Values(1, 3, 5),
702
testing::Bool(), // Read from input directly or place a copy node at start
703
Values(std::make_tuple(cv::Size{8,8},
704
cv::Size{4,4}, cv::Rect{0,0,4,4}),
705
std::make_tuple(cv::Size{8,8},
706
cv::Size{4,4}, cv::Rect{0,0,4,1}),
707
std::make_tuple(cv::Size{8,8},
708
cv::Size{4,4}, cv::Rect{0,1,4,2}),
709
std::make_tuple(cv::Size{8,8},
710
cv::Size{4,4}, cv::Rect{0,2,4,2}),
711
std::make_tuple(cv::Size{64,64},
712
cv::Size{49,49}, cv::Rect{0, 0,49,49}),
713
std::make_tuple(cv::Size{64,64},
714
cv::Size{49,49}, cv::Rect{0, 0,49,11}),
715
std::make_tuple(cv::Size{64,64},
716
cv::Size{49,49}, cv::Rect{0, 9,49,17}),
717
std::make_tuple(cv::Size{64,64},
718
cv::Size{49,49}, cv::Rect{0,39,49,10}))));
719
720
} // namespace opencv_test
721
722