Path: blob/master/modules/gapi/test/gapi_fluid_resize_test.cpp
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3//4// Copyright (C) 2018 Intel Corporation567#include "test_precomp.hpp"89#include "gapi_fluid_test_kernels.hpp"1011namespace opencv_test12{1314using namespace cv::gapi_test_kernels;1516G_TYPED_KERNEL(TCopy, <GMat(GMat)>, "test.fluid.copy")17{18static GMatDesc outMeta(const cv::GMatDesc &in) {19return in;20}21};2223GAPI_FLUID_KERNEL(FCopy, TCopy, false)24{25static const int Window = 1;2627static void run(const cv::gapi::fluid::View &in,28cv::gapi::fluid::Buffer &out)29{30const uint8_t* in_row = in .InLine <uint8_t>(0);31uint8_t* out_row = out.OutLine<uint8_t>();3233for (int i = 0, w = in.length(); i < w; i++)34{35//std::cout << std::setw(4) << int(in_row[i]);36out_row[i] = in_row[i];37}38//std::cout << std::endl;39}40};4142GAPI_FLUID_KERNEL(FResizeNN1Lpi, cv::gapi::core::GResize, false)43{44static const int Window = 1;45static const auto Kind = GFluidKernel::Kind::Resize;4647static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,48cv::gapi::fluid::Buffer& out)4950{51auto length = out.length();52double vRatio = (double)in.meta().size.height / out.meta().size.height;53double hRatio = (double)in.length() / length;54auto y = out.y();55auto inY = in.y();5657for (int l = 0; l < out.lpi(); l++)58{59auto sy = static_cast<int>((y+l) * vRatio);60int idx = sy - inY;6162const auto src = in.InLine <unsigned char>(idx);63auto dst = out.OutLine<unsigned char>(l);6465for (int x = 0; x < length; x++)66{67auto inX = static_cast<int>(x * hRatio);68dst[x] = src[inX];69}70}71}72};7374namespace75{76namespace func77{78template <class Mapper>79void initScratch(const cv::GMatDesc& in, cv::Size outSz, cv::gapi::fluid::Buffer &scratch)80{81CV_Assert(in.depth == CV_8U && in.chan == 1);8283cv::Size scratch_size{static_cast<int>(outSz.width * sizeof(typename Mapper::Unit)), 1};8485cv::GMatDesc desc;86desc.chan = 1;87desc.depth = CV_8UC1;88desc.size = scratch_size;8990cv::gapi::fluid::Buffer buffer(desc);91scratch = std::move(buffer);9293auto mapX = scratch.OutLine<typename Mapper::Unit>();94double hRatio = (double)in.size.width / outSz.width;9596for (int x = 0, w = outSz.width; x < w; x++)97{98mapX[x] = Mapper::map(hRatio, 0, in.size.width, x);99}100}101102template <class Mapper>103inline void calcRow(const cv::gapi::fluid::View& in, cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)104{105double vRatio = (double)in.meta().size.height / out.meta().size.height;106auto mapX = scratch.OutLine<typename Mapper::Unit>();107auto inY = in.y();108auto inH = in.meta().size.height;109auto outY = out.y();110auto length = out.length();111112for (int l = 0; l < out.lpi(); l++)113{114auto mapY = Mapper::map(vRatio, inY, inH, outY + l);115116const auto src0 = in.InLine <unsigned char>(mapY.s0);117const auto src1 = in.InLine <unsigned char>(mapY.s1);118119auto dst = out.OutLine<unsigned char>(l);120121for (int x = 0; x < length; x++)122{123auto alpha0 = mapX[x].alpha0;124auto alpha1 = mapX[x].alpha1;125auto sx0 = mapX[x].s0;126auto sx1 = mapX[x].s1;127128int res0 = src0[sx0]*alpha0 + src0[sx1]*alpha1;129int res1 = src1[sx0]*alpha0 + src1[sx1]*alpha1;130131dst[x] = uchar(( ((mapY.alpha0 * (res0 >> 4)) >> 16) + ((mapY.alpha1 * (res1 >> 4)) >> 16) + 2)>>2);132}133}134}135} // namespace func136137constexpr static const int INTER_RESIZE_COEF_BITS = 11;138constexpr static const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;139140namespace linear141{142struct Mapper143{144struct Unit145{146short alpha0;147short alpha1;148int s0;149int s1;150};151152static inline Unit map(double ratio, int start, int max, int outCoord)153{154auto f = static_cast<float>((outCoord + 0.5f) * ratio - 0.5f);155int s = cvFloor(f);156f -= s;157158Unit u;159160u.s0 = std::max(s - start, 0);161u.s1 = ((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1;162163u.alpha0 = saturate_cast<short>((1.0f - f) * INTER_RESIZE_COEF_SCALE);164u.alpha1 = saturate_cast<short>((f) * INTER_RESIZE_COEF_SCALE);165166return u;167}168};169170} // namespace linear171172namespace areaUpscale173{174struct Mapper175{176struct Unit177{178short alpha0;179short alpha1;180int s0;181int s1;182};183184static inline Unit map(double ratio, int start, int max, int outCoord)185{186int s = cvFloor(outCoord*ratio);187float f = (float)((outCoord+1) - (s+1)/ratio);188f = f <= 0 ? 0.f : f - cvFloor(f);189190Unit u;191192u.s0 = std::max(s - start, 0);193u.s1 = ((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1;194195u.alpha0 = saturate_cast<short>((1.0f - f) * INTER_RESIZE_COEF_SCALE);196u.alpha1 = saturate_cast<short>((f) * INTER_RESIZE_COEF_SCALE);197198return u;199}200};201} // namespace areaUpscale202} // anonymous namespace203204GAPI_FLUID_KERNEL(FResizeLinear1Lpi, cv::gapi::core::GResize, true)205{206static const int Window = 1;207static const auto Kind = GFluidKernel::Kind::Resize;208209static void initScratch(const cv::GMatDesc& in,210cv::Size outSz, double /*fx*/, double /*fy*/, int /*interp*/,211cv::gapi::fluid::Buffer &scratch)212{213func::initScratch<linear::Mapper>(in, outSz, scratch);214}215216static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)217{}218219static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,220cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)221222{223func::calcRow<linear::Mapper>(in, out, scratch);224}225};226227namespace228{229// FIXME230// Move to some common place (to reuse/align with ResizeAgent)231auto startInCoord = [](int outCoord, double ratio) {232return static_cast<int>(outCoord * ratio + 1e-3);233};234auto endInCoord = [](int outCoord, double ratio) {235return static_cast<int>(std::ceil((outCoord + 1) * ratio - 1e-3));236};237} // namespace238239GAPI_FLUID_KERNEL(FResizeArea1Lpi, cv::gapi::core::GResize, false)240{241static const int Window = 1;242static const auto Kind = GFluidKernel::Kind::Resize;243244static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,245cv::gapi::fluid::Buffer& out)246247{248auto firstOutLineIdx = out.y();249auto firstViewLineIdx = in.y();250auto length = out.length();251double vRatio = (double)in.meta().size.height / out.meta().size.height;252double hRatio = (double)in.length() / length;253254for (int l = 0; l < out.lpi(); l++)255{256int outY = firstOutLineIdx + l;257int startY = startInCoord(outY, vRatio);258int endY = endInCoord (outY, vRatio);259260auto dst = out.OutLine<unsigned char>(l);261262for (int x = 0; x < length; x++)263{264float res = 0.0;265266int startX = startInCoord(x, hRatio);267int endX = endInCoord (x, hRatio);268269for (int inY = startY; inY < endY; inY++)270{271double startCoordY = inY / vRatio;272double endCoordY = startCoordY + 1/vRatio;273274if (startCoordY < outY) startCoordY = outY;275if (endCoordY > outY + 1) endCoordY = outY + 1;276277float fracY = static_cast<float>((inY == startY || inY == endY - 1) ? endCoordY - startCoordY : 1/vRatio);278279const auto src = in.InLine <unsigned char>(inY - firstViewLineIdx);280281float rowSum = 0.0f;282283for (int inX = startX; inX < endX; inX++)284{285double startCoordX = inX / hRatio;286double endCoordX = startCoordX + 1/hRatio;287288if (startCoordX < x) startCoordX = x;289if (endCoordX > x + 1) endCoordX = x + 1;290291float fracX = static_cast<float>((inX == startX || inX == endX - 1) ? endCoordX - startCoordX : 1/hRatio);292293rowSum += src[inX] * fracX;294}295res += rowSum * fracY;296}297dst[x] = static_cast<unsigned char>(std::rint(res));298}299}300}301};302303GAPI_FLUID_KERNEL(FResizeAreaUpscale1Lpi, cv::gapi::core::GResize, true)304{305static const int Window = 1;306static const auto Kind = GFluidKernel::Kind::Resize;307308static void initScratch(const cv::GMatDesc& in,309cv::Size outSz, double /*fx*/, double /*fy*/, int /*interp*/,310cv::gapi::fluid::Buffer &scratch)311{312func::initScratch<areaUpscale::Mapper>(in, outSz, scratch);313}314315static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)316{}317318static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int /*interp*/,319cv::gapi::fluid::Buffer& out, cv::gapi::fluid::Buffer &scratch)320{321func::calcRow<areaUpscale::Mapper>(in, out, scratch);322}323};324325#define ADD_RESIZE_KERNEL_WITH_LPI(interp, lpi, scratch) \326struct Resize##interp##lpi##LpiHelper : public FResize##interp##1Lpi { static const int LPI = lpi; }; \327struct FResize##interp##lpi##Lpi : public cv::GFluidKernelImpl<Resize##interp##lpi##LpiHelper, cv::gapi::core::GResize, scratch>{};328329ADD_RESIZE_KERNEL_WITH_LPI(NN, 2, false)330ADD_RESIZE_KERNEL_WITH_LPI(NN, 3, false)331ADD_RESIZE_KERNEL_WITH_LPI(NN, 4, false)332333ADD_RESIZE_KERNEL_WITH_LPI(Linear, 2, true)334ADD_RESIZE_KERNEL_WITH_LPI(Linear, 3, true)335ADD_RESIZE_KERNEL_WITH_LPI(Linear, 4, true)336337ADD_RESIZE_KERNEL_WITH_LPI(Area, 2, false)338ADD_RESIZE_KERNEL_WITH_LPI(Area, 3, false)339ADD_RESIZE_KERNEL_WITH_LPI(Area, 4, false)340341ADD_RESIZE_KERNEL_WITH_LPI(AreaUpscale, 2, true)342ADD_RESIZE_KERNEL_WITH_LPI(AreaUpscale, 3, true)343ADD_RESIZE_KERNEL_WITH_LPI(AreaUpscale, 4, true)344#undef ADD_RESIZE_KERNEL_WITH_LPI345346static auto fluidResizeTestPackage = [](int interpolation, cv::Size szIn, cv::Size szOut, int lpi = 1)347{348using namespace cv;349using namespace cv::gapi;350bool upscale = szIn.width < szOut.width || szIn.height < szOut.height;351352#define RESIZE_CASE(interp, lpi) \353case lpi: pkg = kernels<FCopy, FResize##interp##lpi##Lpi>(); break;354355#define RESIZE_SWITCH(interp) \356switch(lpi) \357{ \358RESIZE_CASE(interp, 1) \359RESIZE_CASE(interp, 2) \360RESIZE_CASE(interp, 3) \361RESIZE_CASE(interp, 4) \362default: CV_Assert(false); \363}364365GKernelPackage pkg;366switch (interpolation)367{368case INTER_NEAREST: RESIZE_SWITCH(NN); break;369case INTER_LINEAR: RESIZE_SWITCH(Linear); break;370case INTER_AREA:371{372if (upscale)373{374RESIZE_SWITCH(AreaUpscale)375}376else377{378RESIZE_SWITCH(Area);379}380}break;381default: CV_Assert(false);382}383return combine(pkg, fluidTestPackage, unite_policy::KEEP);384385#undef RESIZE_SWITCH386#undef RESIZE_CASE387};388389struct ResizeTestFluid : public TestWithParam<std::tuple<int, int, cv::Size, std::tuple<cv::Size, cv::Rect>, int, double>> {};390TEST_P(ResizeTestFluid, SanityTest)391{392int type = 0, interp = 0;393cv::Size sz_in, sz_out;394int lpi = 0;395double tolerance = 0.0;396cv::Rect outRoi;397std::tuple<cv::Size, cv::Rect> outSizeAndRoi;398std::tie(type, interp, sz_in, outSizeAndRoi, lpi, tolerance) = GetParam();399std::tie(sz_out, outRoi) = outSizeAndRoi;400if (outRoi == cv::Rect{}) outRoi = {0,0,sz_out.width,sz_out.height};401if (outRoi.width == 0) outRoi.width = sz_out.width;402double fx = 0, fy = 0;403404cv::Mat in_mat1 (sz_in, type );405cv::Scalar mean = cv::Scalar(127);406cv::Scalar stddev = cv::Scalar(40.f);407408cv::randn(in_mat1, mean, stddev);409410cv::Mat out_mat = cv::Mat::zeros(sz_out, type);411cv::Mat out_mat_ocv = cv::Mat::zeros(sz_out, type);412413cv::GMat in;414auto mid = TBlur3x3::on(in, cv::BORDER_REPLICATE, {});415auto out = cv::gapi::resize(mid, sz_out, fx, fy, interp);416417cv::GComputation c(in, out);418c.apply(in_mat1, out_mat, cv::compile_args(GFluidOutputRois{{outRoi}}, fluidResizeTestPackage(interp, sz_in, sz_out, lpi)));419420cv::Mat mid_mat;421cv::blur(in_mat1, mid_mat, {3,3}, {-1,-1}, cv::BORDER_REPLICATE);422cv::resize(mid_mat, out_mat_ocv, sz_out, fx, fy, interp);423424cv::Mat absDiff;425cv::absdiff(out_mat(outRoi), out_mat_ocv(outRoi), absDiff);426EXPECT_EQ(0, cv::countNonZero(absDiff > tolerance));427}428429INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeTestFluid,430Combine(Values(CV_8UC1),431Values(cv::INTER_NEAREST, cv::INTER_LINEAR),432Values(cv::Size(8, 7),433cv::Size(8, 8),434cv::Size(8, 64),435cv::Size(8, 25),436cv::Size(16, 8),437cv::Size(16, 7)),438Values(std::make_tuple(cv::Size(5, 4), cv::Rect{}),439std::make_tuple(cv::Size(5, 4), cv::Rect{0, 0, 0, 2}),440std::make_tuple(cv::Size(5, 4), cv::Rect{0, 1, 0, 2}),441std::make_tuple(cv::Size(5, 4), cv::Rect{0, 2, 0, 2}),442std::make_tuple(cv::Size(7, 7), cv::Rect{}),443std::make_tuple(cv::Size(7, 7), cv::Rect{0, 0, 0, 3}),444std::make_tuple(cv::Size(7, 7), cv::Rect{0, 2, 0, 2}),445std::make_tuple(cv::Size(7, 7), cv::Rect{0, 4, 0, 3}),446std::make_tuple(cv::Size(8, 4), cv::Rect{}),447std::make_tuple(cv::Size(8, 4), cv::Rect{0, 0, 0, 3}),448std::make_tuple(cv::Size(8, 4), cv::Rect{0, 1, 0, 2}),449std::make_tuple(cv::Size(8, 4), cv::Rect{0, 3, 0, 1})),450Values(1, 2, 3, 4), // lpi451Values(0.0)));452453INSTANTIATE_TEST_CASE_P(ResizeAreaTestCPU, ResizeTestFluid,454Combine(Values(CV_8UC1),455Values(cv::INTER_AREA),456Values(cv::Size(8, 7),457cv::Size(8, 8),458cv::Size(8, 64),459cv::Size(8, 25),460cv::Size(16, 8),461cv::Size(16, 7)),462Values(std::make_tuple(cv::Size(5, 4), cv::Rect{}),463std::make_tuple(cv::Size(5, 4), cv::Rect{0, 0, 0, 2}),464std::make_tuple(cv::Size(5, 4), cv::Rect{0, 1, 0, 2}),465std::make_tuple(cv::Size(5, 4), cv::Rect{0, 2, 0, 2}),466std::make_tuple(cv::Size(7, 7), cv::Rect{}),467std::make_tuple(cv::Size(7, 7), cv::Rect{0, 0, 0, 3}),468std::make_tuple(cv::Size(7, 7), cv::Rect{0, 2, 0, 2}),469std::make_tuple(cv::Size(7, 7), cv::Rect{0, 4, 0, 3}),470std::make_tuple(cv::Size(8, 4), cv::Rect{}),471std::make_tuple(cv::Size(8, 4), cv::Rect{0, 0, 0, 3}),472std::make_tuple(cv::Size(8, 4), cv::Rect{0, 1, 0, 2}),473std::make_tuple(cv::Size(8, 4), cv::Rect{0, 3, 0, 1})),474Values(1, 2, 3, 4), // lpi475// Actually this tolerance only for cases where OpenCV476// uses ResizeAreaFast477Values(1.0)));478479INSTANTIATE_TEST_CASE_P(ResizeUpscaleTestCPU, ResizeTestFluid,480Combine(Values(CV_8UC1),481Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),482Values(cv::Size(1, 5),483cv::Size(3, 5),484cv::Size(7, 5),485cv::Size(1, 7),486cv::Size(3, 7),487cv::Size(7, 7)),488Values(std::make_tuple(cv::Size(8, 8), cv::Rect{0,0,8,2}),489std::make_tuple(cv::Size(8, 8), cv::Rect{0,2,8,2}),490std::make_tuple(cv::Size(8, 8), cv::Rect{0,4,8,2}),491std::make_tuple(cv::Size(8, 8), cv::Rect{0,6,8,2}),492std::make_tuple(cv::Size(8, 8), cv::Rect{0,0,8,8}),493std::make_tuple(cv::Size(16, 8), cv::Rect{}),494std::make_tuple(cv::Size(16, 64), cv::Rect{0, 0,16,16}),495std::make_tuple(cv::Size(16, 64), cv::Rect{0,16,16,16}),496std::make_tuple(cv::Size(16, 64), cv::Rect{0,32,16,16}),497std::make_tuple(cv::Size(16, 64), cv::Rect{0,48,16,16}),498std::make_tuple(cv::Size(16, 64), cv::Rect{0, 0,16,64}),499std::make_tuple(cv::Size(16, 25), cv::Rect{0, 0,16, 7}),500std::make_tuple(cv::Size(16, 25), cv::Rect{0, 7,16, 6}),501std::make_tuple(cv::Size(16, 25), cv::Rect{0,13,16, 6}),502std::make_tuple(cv::Size(16, 25), cv::Rect{0,19,16, 6}),503std::make_tuple(cv::Size(16, 25), cv::Rect{0, 0,16, 7}),504std::make_tuple(cv::Size(16, 25), cv::Rect{0, 7,16, 7}),505std::make_tuple(cv::Size(16, 25), cv::Rect{0,14,16, 7}),506std::make_tuple(cv::Size(16, 25), cv::Rect{0,21,16, 4}),507std::make_tuple(cv::Size(16, 25), cv::Rect{0, 0,16,25}),508std::make_tuple(cv::Size(16, 7), cv::Rect{}),509std::make_tuple(cv::Size(16, 8), cv::Rect{})),510Values(1, 2, 3, 4), // lpi511Values(0.0)));512513INSTANTIATE_TEST_CASE_P(ResizeUpscaleOneDimDownscaleAnother, ResizeTestFluid,514Combine(Values(CV_8UC1),515Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),516Values(cv::Size(6, 6),517cv::Size(8, 7),518cv::Size(8, 8),519cv::Size(8, 10),520cv::Size(10, 8),521cv::Size(10, 7)),522Values(std::make_tuple(cv::Size(11, 5), cv::Rect{}),523std::make_tuple(cv::Size(11, 5), cv::Rect{0, 0, 0, 2}),524std::make_tuple(cv::Size(11, 5), cv::Rect{0, 2, 0, 2}),525std::make_tuple(cv::Size(11, 5), cv::Rect{0, 4, 0, 1}),526std::make_tuple(cv::Size(12, 2), cv::Rect{}),527std::make_tuple(cv::Size(12, 2), cv::Rect{0, 0, 0, 1}),528std::make_tuple(cv::Size(12, 2), cv::Rect{0, 1, 0, 1}),529std::make_tuple(cv::Size(23, 3), cv::Rect{}),530std::make_tuple(cv::Size(23, 3), cv::Rect{0, 0, 0, 1}),531std::make_tuple(cv::Size(23, 3), cv::Rect{0, 1, 0, 1}),532std::make_tuple(cv::Size(23, 3), cv::Rect{0, 2, 0, 1}),533std::make_tuple(cv::Size(3, 24), cv::Rect{}),534std::make_tuple(cv::Size(3, 24), cv::Rect{0, 0, 0, 6}),535std::make_tuple(cv::Size(3, 24), cv::Rect{0, 6, 0, 6}),536std::make_tuple(cv::Size(3, 24), cv::Rect{0, 12, 0, 6}),537std::make_tuple(cv::Size(3, 24), cv::Rect{0, 18, 0, 6}),538std::make_tuple(cv::Size(5, 11), cv::Rect{}),539std::make_tuple(cv::Size(5, 11), cv::Rect{0, 0, 0, 3}),540std::make_tuple(cv::Size(5, 11), cv::Rect{0, 3, 0, 3}),541std::make_tuple(cv::Size(5, 11), cv::Rect{0, 6, 0, 3}),542std::make_tuple(cv::Size(5, 11), cv::Rect{0, 9, 0, 2})),543Values(1, 2, 3, 4), // lpi544Values(0.0)));545546INSTANTIATE_TEST_CASE_P(Resize400_384TestCPU, ResizeTestFluid,547Combine(Values(CV_8UC1),548Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),549Values(cv::Size(128, 400)),550Values(std::make_tuple(cv::Size(128, 384), cv::Rect{})),551Values(1, 2, 3, 4), // lpi552Values(0.0)));553554INSTANTIATE_TEST_CASE_P(Resize220_400TestCPU, ResizeTestFluid,555Combine(Values(CV_8UC1),556Values(cv::INTER_LINEAR),557Values(cv::Size(220, 220)),558Values(std::make_tuple(cv::Size(400, 400), cv::Rect{})),559Values(1, 2, 3, 4), // lpi560Values(0.0)));561562static auto cvBlur = [](const cv::Mat& in, cv::Mat& out, int kernelSize)563{564if (kernelSize == 1)565{566out = in;567}568else569{570cv::blur(in, out, {kernelSize, kernelSize});571}572};573574using SizesWithRois = std::tuple<cv::Size, cv::Rect, cv::Size, cv::Rect>;575struct ResizeAndAnotherReaderTest : public TestWithParam<std::tuple<int, int, bool, SizesWithRois>>{};576TEST_P(ResizeAndAnotherReaderTest, SanityTest)577{578bool readFromInput = false;579int interp = -1, kernelSize = -1;580SizesWithRois sizesWithRois;581std::tie(interp, kernelSize, readFromInput, sizesWithRois) = GetParam();582583cv::Size sz, resizedSz;584cv::Rect roi, resizedRoi;585std::tie(sz, roi, resizedSz, resizedRoi) = sizesWithRois;586587cv::Mat in_mat(sz, CV_8UC1);588cv::Scalar mean = cv::Scalar(127);589cv::Scalar stddev = cv::Scalar(40.f);590cv::randn(in_mat, mean, stddev);591592cv::Mat gapi_resize_out = cv::Mat::zeros(resizedSz, CV_8UC1);593cv::Mat gapi_blur_out = cv::Mat::zeros(sz, CV_8UC1);594595auto blur = kernelSize == 1 ? &TBlur1x1::on : kernelSize == 3 ? &TBlur3x3::on : &TBlur5x5::on;596597cv::GMat in, resize_out, blur_out;598599if (readFromInput)600{601resize_out = gapi::resize(in, resizedSz, 0, 0, interp);602blur_out = blur(in, cv::BORDER_DEFAULT, {});603}604else605{606auto mid = TCopy::on(in);607resize_out = gapi::resize(mid, resizedSz, 0, 0, interp);608blur_out = blur(mid, cv::BORDER_DEFAULT, {});609}610611cv::GComputation c(GIn(in), GOut(resize_out, blur_out));612c.apply(gin(in_mat), gout(gapi_resize_out, gapi_blur_out), cv::compile_args(GFluidOutputRois{{resizedRoi, roi}},613fluidResizeTestPackage(interp, sz, resizedSz)));614615cv::Mat ocv_resize_out = cv::Mat::zeros(resizedSz, CV_8UC1);616cv::resize(in_mat, ocv_resize_out, resizedSz, 0, 0, interp);617cv::Mat ocv_blur_out = cv::Mat::zeros(sz, CV_8UC1);618cvBlur(in_mat, ocv_blur_out, kernelSize);619620EXPECT_EQ(0, cv::countNonZero(gapi_resize_out(resizedRoi) != ocv_resize_out(resizedRoi)));621EXPECT_EQ(0, cv::countNonZero(gapi_blur_out(roi) != ocv_blur_out(roi)));622}623624INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeAndAnotherReaderTest,625Combine(Values(cv::INTER_NEAREST, cv::INTER_LINEAR),626Values(1, 3, 5),627testing::Bool(), // Read from input directly or place a copy node at start628Values(std::make_tuple(cv::Size{8,8}, cv::Rect{0,0,8,8},629cv::Size{4,4}, cv::Rect{0,0,4,4}),630std::make_tuple(cv::Size{8,8}, cv::Rect{0,0,8,2},631cv::Size{4,4}, cv::Rect{0,0,4,1}),632std::make_tuple(cv::Size{8,8}, cv::Rect{0,2,8,4},633cv::Size{4,4}, cv::Rect{0,1,4,2}),634std::make_tuple(cv::Size{8,8}, cv::Rect{0,4,8,4},635cv::Size{4,4}, cv::Rect{0,2,4,2}),636std::make_tuple(cv::Size{64,64}, cv::Rect{0, 0,64,64},637cv::Size{49,49}, cv::Rect{0, 0,49,49}),638std::make_tuple(cv::Size{64,64}, cv::Rect{0, 0,64,15},639cv::Size{49,49}, cv::Rect{0, 0,49,11}),640std::make_tuple(cv::Size{64,64}, cv::Rect{0,11,64,23},641cv::Size{49,49}, cv::Rect{0, 9,49,17}),642std::make_tuple(cv::Size{64,64}, cv::Rect{0,50,64,14},643cv::Size{49,49}, cv::Rect{0,39,49,10}))));644645struct BlursAfterResizeTest : public TestWithParam<std::tuple<int, int, int, bool, std::tuple<cv::Size, cv::Size, cv::Rect>>>{};646TEST_P(BlursAfterResizeTest, SanityTest)647{648bool readFromInput = false;649int interp = -1, kernelSize1 = -1, kernelSize2 = -1;650std::tuple<cv::Size, cv::Size, cv::Rect> sizesWithRoi;651std::tie(interp, kernelSize1, kernelSize2, readFromInput, sizesWithRoi) = GetParam();652653cv::Size inSz, outSz;654cv::Rect outRoi;655std::tie(inSz, outSz, outRoi) = sizesWithRoi;656657cv::Mat in_mat(inSz, CV_8UC1);658cv::Scalar mean = cv::Scalar(127);659cv::Scalar stddev = cv::Scalar(40.f);660cv::randn(in_mat, mean, stddev);661cv::Mat gapi_out1 = cv::Mat::zeros(outSz, CV_8UC1);662cv::Mat gapi_out2 = cv::Mat::zeros(outSz, CV_8UC1);663664auto blur1 = kernelSize1 == 1 ? &TBlur1x1::on : kernelSize1 == 3 ? &TBlur3x3::on : &TBlur5x5::on;665auto blur2 = kernelSize2 == 1 ? &TBlur1x1::on : kernelSize2 == 3 ? &TBlur3x3::on : &TBlur5x5::on;666667cv::GMat in, out1, out2;668if (readFromInput)669{670auto resized = gapi::resize(in, outSz, 0, 0, interp);671out1 = blur1(resized, cv::BORDER_DEFAULT, {});672out2 = blur2(resized, cv::BORDER_DEFAULT, {});673}674else675{676auto mid = TCopy::on(in);677auto resized = gapi::resize(mid, outSz, 0, 0, interp);678out1 = blur1(resized, cv::BORDER_DEFAULT, {});679out2 = blur2(resized, cv::BORDER_DEFAULT, {});680}681682cv::GComputation c(GIn(in), GOut(out1, out2));683c.apply(gin(in_mat), gout(gapi_out1, gapi_out2), cv::compile_args(GFluidOutputRois{{outRoi, outRoi}},684fluidResizeTestPackage(interp, inSz, outSz)));685686cv::Mat ocv_out1 = cv::Mat::zeros(outSz, CV_8UC1);687cv::Mat ocv_out2 = cv::Mat::zeros(outSz, CV_8UC1);688cv::Mat resized = cv::Mat::zeros(outSz, CV_8UC1);689cv::resize(in_mat, resized, outSz, 0, 0, interp);690cvBlur(resized, ocv_out1, kernelSize1);691cvBlur(resized, ocv_out2, kernelSize2);692693EXPECT_EQ(0, cv::countNonZero(gapi_out1(outRoi) != ocv_out1(outRoi)));694EXPECT_EQ(0, cv::countNonZero(gapi_out2(outRoi) != ocv_out2(outRoi)));695}696697INSTANTIATE_TEST_CASE_P(ResizeTestCPU, BlursAfterResizeTest,698Combine(Values(cv::INTER_NEAREST, cv::INTER_LINEAR),699Values(1, 3, 5),700Values(1, 3, 5),701testing::Bool(), // Read from input directly or place a copy node at start702Values(std::make_tuple(cv::Size{8,8},703cv::Size{4,4}, cv::Rect{0,0,4,4}),704std::make_tuple(cv::Size{8,8},705cv::Size{4,4}, cv::Rect{0,0,4,1}),706std::make_tuple(cv::Size{8,8},707cv::Size{4,4}, cv::Rect{0,1,4,2}),708std::make_tuple(cv::Size{8,8},709cv::Size{4,4}, cv::Rect{0,2,4,2}),710std::make_tuple(cv::Size{64,64},711cv::Size{49,49}, cv::Rect{0, 0,49,49}),712std::make_tuple(cv::Size{64,64},713cv::Size{49,49}, cv::Rect{0, 0,49,11}),714std::make_tuple(cv::Size{64,64},715cv::Size{49,49}, cv::Rect{0, 9,49,17}),716std::make_tuple(cv::Size{64,64},717cv::Size{49,49}, cv::Rect{0,39,49,10}))));718719} // namespace opencv_test720721722