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.
5 // Copyright (C) 2018-2019 Intel Corporation
8 #include "test_precomp.hpp"
10 #include "gapi_fluid_test_kernels.hpp"
15 using namespace cv::gapi_test_kernels;
17 G_TYPED_KERNEL(TCopy, <GMat(GMat)>, "test.fluid.copy")
19 static GMatDesc outMeta(const cv::GMatDesc &in) {
24 GAPI_FLUID_KERNEL(FCopy, TCopy, false)
26 static const int Window = 1;
28 static void run(const cv::gapi::fluid::View &in,
29 cv::gapi::fluid::Buffer &out)
31 const uint8_t* in_row = in .InLine <uint8_t>(0);
32 uint8_t* out_row = out.OutLine<uint8_t>();
34 for (int i = 0, w = in.length(); i < w; i++)
36 //std::cout << std::setw(4) << int(in_row[i]);
37 out_row[i] = in_row[i];
39 //std::cout << std::endl;
43 GAPI_FLUID_KERNEL(FResizeNN1Lpi, cv::gapi::core::GResize, false)
45 static const int Window = 1;
46 static const auto Kind = GFluidKernel::Kind::Resize;
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)
52 auto length = out.length();
53 double vRatio = (double)in.meta().size.height / out.meta().size.height;
54 double hRatio = (double)in.length() / length;
58 for (int l = 0; l < out.lpi(); l++)
60 auto sy = static_cast<int>((y+l) * vRatio);
63 const auto src = in.InLine <unsigned char>(idx);
64 auto dst = out.OutLine<unsigned char>(l);
66 for (int x = 0; x < length; x++)
68 auto inX = static_cast<int>(x * hRatio);
79 template <class Mapper>
80 void initScratch(const cv::GMatDesc& in, cv::Size outSz, cv::gapi::fluid::Buffer &scratch)
82 CV_Assert(in.depth == CV_8U && in.chan == 1);
84 cv::Size scratch_size{static_cast<int>(outSz.width * sizeof(typename Mapper::Unit)), 1};
89 desc.size = scratch_size;
91 cv::gapi::fluid::Buffer buffer(desc);
92 scratch = std::move(buffer);
94 auto mapX = scratch.OutLine<typename Mapper::Unit>();
95 double hRatio = (double)in.size.width / outSz.width;
97 for (int x = 0, w = outSz.width; x < w; x++)
99 mapX[x] = Mapper::map(hRatio, 0, in.size.width, x);
103 template <class Mapper>
104 inline void calcRow(const cv::gapi::fluid::View& in, cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)
106 double vRatio = (double)in.meta().size.height / out.meta().size.height;
107 auto mapX = scratch.OutLine<typename Mapper::Unit>();
109 auto inH = in.meta().size.height;
111 auto length = out.length();
113 for (int l = 0; l < out.lpi(); l++)
115 auto mapY = Mapper::map(vRatio, inY, inH, outY + l);
117 const auto src0 = in.InLine <unsigned char>(mapY.s0);
118 const auto src1 = in.InLine <unsigned char>(mapY.s1);
120 auto dst = out.OutLine<unsigned char>(l);
122 for (int x = 0; x < length; x++)
124 auto alpha0 = mapX[x].alpha0;
125 auto alpha1 = mapX[x].alpha1;
126 auto sx0 = mapX[x].s0;
127 auto sx1 = mapX[x].s1;
129 int res0 = src0[sx0]*alpha0 + src0[sx1]*alpha1;
130 int res1 = src1[sx0]*alpha0 + src1[sx1]*alpha1;
132 dst[x] = uchar(( ((mapY.alpha0 * (res0 >> 4)) >> 16) + ((mapY.alpha1 * (res1 >> 4)) >> 16) + 2)>>2);
138 constexpr static const int INTER_RESIZE_COEF_BITS = 11;
139 constexpr static const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;
153 static inline Unit map(double ratio, int start, int max, int outCoord)
155 auto f = static_cast<float>((outCoord + 0.5f) * ratio - 0.5f);
161 u.s0 = std::max(s - start, 0);
162 u.s1 = ((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1;
164 u.alpha0 = saturate_cast<short>((1.0f - f) * INTER_RESIZE_COEF_SCALE);
165 u.alpha1 = saturate_cast<short>((f) * INTER_RESIZE_COEF_SCALE);
171 } // namespace linear
173 namespace areaUpscale
185 static inline Unit map(double ratio, int start, int max, int outCoord)
187 int s = cvFloor(outCoord*ratio);
188 float f = (float)((outCoord+1) - (s+1)/ratio);
189 f = f <= 0 ? 0.f : f - cvFloor(f);
193 u.s0 = std::max(s - start, 0);
194 u.s1 = ((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1;
196 u.alpha0 = saturate_cast<short>((1.0f - f) * INTER_RESIZE_COEF_SCALE);
197 u.alpha1 = saturate_cast<short>((f) * INTER_RESIZE_COEF_SCALE);
202 } // namespace areaUpscale
203 } // anonymous namespace
205 GAPI_FLUID_KERNEL(FResizeLinear1Lpi, cv::gapi::core::GResize, true)
207 static const int Window = 1;
208 static const auto Kind = GFluidKernel::Kind::Resize;
210 static void initScratch(const cv::GMatDesc& in,
211 cv::Size outSz, double /*fx*/, double /*fy*/, int /*interp*/,
212 cv::gapi::fluid::Buffer &scratch)
214 func::initScratch<linear::Mapper>(in, outSz, scratch);
217 static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)
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)
224 func::calcRow<linear::Mapper>(in, out, scratch);
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);
235 auto endInCoord = [](int outCoord, double ratio) {
236 return static_cast<int>(std::ceil((outCoord + 1) * ratio - 1e-3));
240 GAPI_FLUID_KERNEL(FResizeArea1Lpi, cv::gapi::core::GResize, false)
242 static const int Window = 1;
243 static const auto Kind = GFluidKernel::Kind::Resize;
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)
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;
255 for (int l = 0; l < out.lpi(); l++)
257 int outY = firstOutLineIdx + l;
258 int startY = startInCoord(outY, vRatio);
259 int endY = endInCoord (outY, vRatio);
261 auto dst = out.OutLine<unsigned char>(l);
263 for (int x = 0; x < length; x++)
267 int startX = startInCoord(x, hRatio);
268 int endX = endInCoord (x, hRatio);
270 for (int inY = startY; inY < endY; inY++)
272 double startCoordY = inY / vRatio;
273 double endCoordY = startCoordY + 1/vRatio;
275 if (startCoordY < outY) startCoordY = outY;
276 if (endCoordY > outY + 1) endCoordY = outY + 1;
278 float fracY = static_cast<float>((inY == startY || inY == endY - 1) ? endCoordY - startCoordY : 1/vRatio);
280 const auto src = in.InLine <unsigned char>(inY - firstViewLineIdx);
284 for (int inX = startX; inX < endX; inX++)
286 double startCoordX = inX / hRatio;
287 double endCoordX = startCoordX + 1/hRatio;
289 if (startCoordX < x) startCoordX = x;
290 if (endCoordX > x + 1) endCoordX = x + 1;
292 float fracX = static_cast<float>((inX == startX || inX == endX - 1) ? endCoordX - startCoordX : 1/hRatio);
294 rowSum += src[inX] * fracX;
296 res += rowSum * fracY;
298 dst[x] = static_cast<unsigned char>(std::rint(res));
304 GAPI_FLUID_KERNEL(FResizeAreaUpscale1Lpi, cv::gapi::core::GResize, true)
306 static const int Window = 1;
307 static const auto Kind = GFluidKernel::Kind::Resize;
309 static void initScratch(const cv::GMatDesc& in,
310 cv::Size outSz, double /*fx*/, double /*fy*/, int /*interp*/,
311 cv::gapi::fluid::Buffer &scratch)
313 func::initScratch<areaUpscale::Mapper>(in, outSz, scratch);
316 static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)
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)
322 func::calcRow<areaUpscale::Mapper>(in, out, scratch);
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>{};
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)
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)
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)
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
347 static auto fluidResizeTestPackage = [](int interpolation, cv::Size szIn, cv::Size szOut, int lpi = 1)
350 using namespace cv::gapi;
351 bool upscale = szIn.width < szOut.width || szIn.height < szOut.height;
353 #define RESIZE_CASE(interp, lpi) \
354 case lpi: pkg = kernels<FCopy, FResize##interp##lpi##Lpi>(); break;
356 #define RESIZE_SWITCH(interp) \
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); \
367 switch (interpolation)
369 case INTER_NEAREST: RESIZE_SWITCH(NN); break;
370 case INTER_LINEAR: RESIZE_SWITCH(Linear); break;
375 RESIZE_SWITCH(AreaUpscale)
382 default: CV_Assert(false);
384 return combine(pkg, fluidTestPackage, unite_policy::KEEP);
390 struct ResizeTestFluid : public TestWithParam<std::tuple<int, int, cv::Size, std::tuple<cv::Size, cv::Rect>, int, double>> {};
391 TEST_P(ResizeTestFluid, SanityTest)
393 int type = 0, interp = 0;
394 cv::Size sz_in, sz_out;
396 double tolerance = 0.0;
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;
405 cv::Mat in_mat1 (sz_in, type );
406 cv::Scalar mean = cv::Scalar(127);
407 cv::Scalar stddev = cv::Scalar(40.f);
409 cv::randn(in_mat1, mean, stddev);
411 cv::Mat out_mat = cv::Mat::zeros(sz_out, type);
412 cv::Mat out_mat_ocv = cv::Mat::zeros(sz_out, type);
415 auto mid = TBlur3x3::on(in, cv::BORDER_REPLICATE, {});
416 auto out = cv::gapi::resize(mid, sz_out, fx, fy, interp);
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)));
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);
426 cv::absdiff(out_mat(outRoi), out_mat_ocv(outRoi), absDiff);
427 EXPECT_EQ(0, cv::countNonZero(absDiff > tolerance));
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),
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
454 INSTANTIATE_TEST_CASE_P(ResizeAreaTestCPU, ResizeTestFluid,
455 Combine(Values(CV_8UC1),
456 Values(cv::INTER_AREA),
457 Values(cv::Size(8, 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
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),
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
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),
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
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
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
563 static auto cvBlur = [](const cv::Mat& in, cv::Mat& out, int kernelSize)
571 cv::blur(in, out, {kernelSize, kernelSize});
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)
579 bool readFromInput = false;
580 int interp = -1, kernelSize = -1;
581 SizesWithRois sizesWithRois;
582 std::tie(interp, kernelSize, readFromInput, sizesWithRois) = GetParam();
584 cv::Size sz, resizedSz;
585 cv::Rect roi, resizedRoi;
586 std::tie(sz, roi, resizedSz, resizedRoi) = sizesWithRois;
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);
593 cv::Mat gapi_resize_out = cv::Mat::zeros(resizedSz, CV_8UC1);
594 cv::Mat gapi_blur_out = cv::Mat::zeros(sz, CV_8UC1);
596 auto blur = kernelSize == 1 ? &TBlur1x1::on : kernelSize == 3 ? &TBlur3x3::on : &TBlur5x5::on;
598 cv::GMat in, resize_out, blur_out;
602 resize_out = gapi::resize(in, resizedSz, 0, 0, interp);
603 blur_out = blur(in, cv::BORDER_DEFAULT, {});
607 auto mid = TCopy::on(in);
608 resize_out = gapi::resize(mid, resizedSz, 0, 0, interp);
609 blur_out = blur(mid, cv::BORDER_DEFAULT, {});
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)));
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);
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)));
625 INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeAndAnotherReaderTest,
626 Combine(Values(cv::INTER_NEAREST, cv::INTER_LINEAR),
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}))));
646 struct BlursAfterResizeTest : public TestWithParam<std::tuple<int, int, int, bool, std::tuple<cv::Size, cv::Size, cv::Rect>>>{};
647 TEST_P(BlursAfterResizeTest, SanityTest)
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();
654 cv::Size inSz, outSz;
656 std::tie(inSz, outSz, outRoi) = sizesWithRoi;
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);
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;
668 cv::GMat in, out1, out2;
671 auto resized = gapi::resize(in, outSz, 0, 0, interp);
672 out1 = blur1(resized, cv::BORDER_DEFAULT, {});
673 out2 = blur2(resized, cv::BORDER_DEFAULT, {});
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, {});
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)));
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);
694 EXPECT_EQ(0, cv::countNonZero(gapi_out1(outRoi) != ocv_out1(outRoi)));
695 EXPECT_EQ(0, cv::countNonZero(gapi_out2(outRoi) != ocv_out2(outRoi)));
698 INSTANTIATE_TEST_CASE_P(ResizeTestCPU, BlursAfterResizeTest,
699 Combine(Values(cv::INTER_NEAREST, cv::INTER_LINEAR),
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}))));
720 } // namespace opencv_test