1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Merge pull request #21157 from alexgiving:atrutnev/move_resize

GAPI: Move Resize kernel from core to imgproc

* Move Resize kernel from core to imgproc

* Applied style comments

* Adding backward compatibility

* Applied Asya PR
This commit is contained in:
Trutnev Aleksei
2021-12-29 18:13:43 +03:00
committed by GitHub
parent 80c2fefc43
commit 43c04c29ce
26 changed files with 640 additions and 626 deletions
@@ -462,30 +462,6 @@ GAPI_OCV_KERNEL(GCPUMerge4, cv::gapi::core::GMerge4)
}
};
GAPI_OCV_KERNEL(GCPUResize, cv::gapi::core::GResize)
{
static void run(const cv::Mat& in, cv::Size sz, double fx, double fy, int interp, cv::Mat &out)
{
cv::resize(in, out, sz, fx, fy, interp);
}
};
GAPI_OCV_KERNEL(GCPUResizeP, cv::gapi::core::GResizeP)
{
static void run(const cv::Mat& in, cv::Size out_sz, int interp, cv::Mat& out)
{
int inH = in.rows / 3;
int inW = in.cols;
int outH = out.rows / 3;
int outW = out.cols;
for (int i = 0; i < 3; i++) {
auto in_plane = in(cv::Rect(0, i*inH, inW, inH));
auto out_plane = out(cv::Rect(0, i*outH, outW, outH));
cv::resize(in_plane, out_plane, out_sz, 0, 0, interp);
}
}
};
GAPI_OCV_KERNEL(GCPURemap, cv::gapi::core::GRemap)
{
static void run(const cv::Mat& in, const cv::Mat& x, const cv::Mat& y, int a, int b, cv::Scalar s, cv::Mat& out)
@@ -775,8 +751,6 @@ cv::GKernelPackage cv::gapi::core::cpu::kernels()
, GCPUInRange
, GCPUSplit3
, GCPUSplit4
, GCPUResize
, GCPUResizeP
, GCPUMerge3
, GCPUMerge4
, GCPURemap
@@ -28,6 +28,30 @@ namespace {
}
}
GAPI_OCV_KERNEL(GCPUResize, cv::gapi::imgproc::GResize)
{
static void run(const cv::Mat& in, cv::Size sz, double fx, double fy, int interp, cv::Mat &out)
{
cv::resize(in, out, sz, fx, fy, interp);
}
};
GAPI_OCV_KERNEL(GCPUResizeP, cv::gapi::imgproc::GResizeP)
{
static void run(const cv::Mat& in, cv::Size out_sz, int interp, cv::Mat& out)
{
int inH = in.rows / 3;
int inW = in.cols;
int outH = out.rows / 3;
int outW = out.cols;
for (int i = 0; i < 3; i++) {
auto in_plane = in(cv::Rect(0, i*inH, inW, inH));
auto out_plane = out(cv::Rect(0, i*outH, outW, outH));
cv::resize(in_plane, out_plane, out_sz, 0, 0, interp);
}
}
};
GAPI_OCV_KERNEL(GCPUSepFilter, cv::gapi::imgproc::GSepFilter)
{
static void run(const cv::Mat& in, int ddepth, const cv::Mat& kernX, const cv::Mat& kernY, const cv::Point& anchor, const cv::Scalar& delta,
@@ -617,6 +641,8 @@ cv::GKernelPackage cv::gapi::imgproc::cpu::kernels()
{
static auto pkg = cv::gapi::kernels
< GCPUFilter2D
, GCPUResize
, GCPUResizeP
, GCPUSepFilter
, GCPUBoxFilter
, GCPUBlur
@@ -23,10 +23,6 @@
#include <opencv2/gapi/fluid/gfluidkernel.hpp>
#include <opencv2/gapi/fluid/core.hpp>
#if CV_SSE4_1
#include "gfluidcore_simd_sse41.hpp"
#endif
#include "gfluidbuffer_priv.hpp"
#include "gfluidbackend.hpp"
#include "gfluidutils.hpp"
@@ -2760,301 +2756,6 @@ GAPI_FLUID_KERNEL(GFluidPhase, cv::gapi::core::GPhase, false)
}
};
template<typename T, typename Mapper, int chanNum>
struct LinearScratchDesc {
using alpha_t = typename Mapper::alpha_type;
using index_t = typename Mapper::index_type;
alpha_t* alpha;
alpha_t* clone;
index_t* mapsx;
alpha_t* beta;
index_t* mapsy;
T* tmp;
LinearScratchDesc(int /*inW*/, int /*inH*/, int outW, int outH, void* data) {
alpha = reinterpret_cast<alpha_t*>(data);
clone = reinterpret_cast<alpha_t*>(alpha + outW);
mapsx = reinterpret_cast<index_t*>(clone + outW*4);
beta = reinterpret_cast<alpha_t*>(mapsx + outW);
mapsy = reinterpret_cast<index_t*>(beta + outH);
tmp = reinterpret_cast<T*> (mapsy + outH*2);
}
static int bufSize(int inW, int /*inH*/, int outW, int outH, int lpi) {
auto size = outW * sizeof(alpha_t) +
outW * sizeof(alpha_t) * 4 + // alpha clones
outW * sizeof(index_t) +
outH * sizeof(alpha_t) +
outH * sizeof(index_t) * 2 +
inW * sizeof(T) * lpi * chanNum;
return static_cast<int>(size);
}
};
static inline double invRatio(int inSz, int outSz) {
return static_cast<double>(outSz) / inSz;
}
static inline double ratio(int inSz, int outSz) {
return 1 / invRatio(inSz, outSz);
}
template<typename T, typename Mapper, int chanNum = 1>
static inline void initScratchLinear(const cv::GMatDesc& in,
const Size& outSz,
cv::gapi::fluid::Buffer& scratch,
int lpi) {
using alpha_type = typename Mapper::alpha_type;
static const auto unity = Mapper::unity;
auto inSz = in.size;
auto sbufsize = LinearScratchDesc<T, Mapper, chanNum>::bufSize(inSz.width, inSz.height, outSz.width, outSz.height, lpi);
Size scratch_size{sbufsize, 1};
cv::GMatDesc desc;
desc.chan = 1;
desc.depth = CV_8UC1;
desc.size = scratch_size;
cv::gapi::fluid::Buffer buffer(desc);
scratch = std::move(buffer);
double hRatio = ratio(in.size.width, outSz.width);
double vRatio = ratio(in.size.height, outSz.height);
LinearScratchDesc<T, Mapper, chanNum> scr(inSz.width, inSz.height, outSz.width, outSz.height, scratch.OutLineB());
auto *alpha = scr.alpha;
auto *clone = scr.clone;
auto *index = scr.mapsx;
for (int x = 0; x < outSz.width; x++) {
auto map = Mapper::map(hRatio, 0, in.size.width, x);
auto alpha0 = map.alpha0;
auto index0 = map.index0;
// TRICK:
// Algorithm takes pair of input pixels, sx0'th and sx1'th,
// and compute result as alpha0*src[sx0] + alpha1*src[sx1].
// By definition: sx1 == sx0 + 1 either sx1 == sx0, and
// alpha0 + alpha1 == unity (scaled appropriately).
// Here we modify formulas for alpha0 and sx1: by assuming
// that sx1 == sx0 + 1 always, and patching alpha0 so that
// result remains intact.
// Note that we need in.size.width >= 2, for both sx0 and
// sx0+1 were indexing pixels inside the input's width.
if (map.index1 != map.index0 + 1) {
GAPI_DbgAssert(map.index1 == map.index0);
GAPI_DbgAssert(in.size.width >= 2);
if (map.index0 < in.size.width-1) {
// sx1=sx0+1 fits inside row,
// make sure alpha0=unity and alpha1=0,
// so that result equals src[sx0]*unity
alpha0 = saturate_cast<alpha_type>(unity);
} else {
// shift sx0 to left by 1 pixel,
// and make sure that alpha0=0 and alpha1==1,
// so that result equals to src[sx0+1]*unity
alpha0 = 0;
index0--;
}
}
alpha[x] = alpha0;
index[x] = index0;
for (int l = 0; l < 4; l++) {
clone[4*x + l] = alpha0;
}
}
auto *beta = scr.beta;
auto *index_y = scr.mapsy;
for (int y = 0; y < outSz.height; y++) {
auto mapY = Mapper::map(vRatio, 0, in.size.height, y);
beta[y] = mapY.alpha0;
index_y[y] = mapY.index0;
index_y[outSz.height + y] = mapY.index1;
}
}
template<typename F, typename I>
struct MapperUnit {
F alpha0, alpha1;
I index0, index1;
};
inline static uint8_t calc(short alpha0, uint8_t src0, short alpha1, uint8_t src1) {
constexpr static const int half = 1 << 14;
return (src0 * alpha0 + src1 * alpha1 + half) >> 15;
}
struct Mapper {
constexpr static const int ONE = 1 << 15;
typedef short alpha_type;
typedef short index_type;
constexpr static const int unity = ONE;
typedef MapperUnit<short, short> Unit;
static inline Unit map(double ratio, int start, int max, int outCoord) {
float f = static_cast<float>((outCoord + 0.5) * ratio - 0.5);
int s = cvFloor(f);
f -= s;
Unit u;
u.index0 = static_cast<short>(std::max(s - start, 0));
u.index1 = static_cast<short>(((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1);
u.alpha0 = saturate_cast<short>(ONE * (1.0f - f));
u.alpha1 = saturate_cast<short>(ONE * f);
return u;
}
};
template<typename T, class Mapper, int numChan>
static void calcRowLinearC(const cv::gapi::fluid::View & in,
cv::gapi::fluid::Buffer& out,
cv::gapi::fluid::Buffer& scratch) {
using alpha_type = typename Mapper::alpha_type;
auto inSz = in.meta().size;
auto outSz = out.meta().size;
auto inY = in.y();
int outY = out.y();
int lpi = out.lpi();
GAPI_DbgAssert(outY + lpi <= outSz.height);
GAPI_DbgAssert(lpi <= 4);
LinearScratchDesc<T, Mapper, numChan> scr(inSz.width, inSz.height, outSz.width, outSz.height, scratch.OutLineB());
const auto *alpha = scr.alpha;
const auto *mapsx = scr.mapsx;
const auto *beta_0 = scr.beta;
const auto *mapsy = scr.mapsy;
const auto *beta = beta_0 + outY;
const T *src0[4];
const T *src1[4];
T* dst[4];
for (int l = 0; l < lpi; l++) {
auto index0 = mapsy[outY + l] - inY;
auto index1 = mapsy[outSz.height + outY + l] - inY;
src0[l] = in.InLine<const T>(index0);
src1[l] = in.InLine<const T>(index1);
dst[l] = out.OutLine<T>(l);
}
#if 0 // Disabling SSE4.1 path due to Valgrind issues: https://github.com/opencv/opencv/issues/21097
#if CV_SSE4_1
const auto* clone = scr.clone;
auto* tmp = scr.tmp;
if (inSz.width >= 16 && outSz.width >= 16)
{
sse42::calcRowLinear_8UC_Impl_<numChan>(reinterpret_cast<uint8_t**>(dst),
reinterpret_cast<const uint8_t**>(src0),
reinterpret_cast<const uint8_t**>(src1),
reinterpret_cast<const short*>(alpha),
reinterpret_cast<const short*>(clone),
reinterpret_cast<const short*>(mapsx),
reinterpret_cast<const short*>(beta),
reinterpret_cast<uint8_t*>(tmp),
inSz, outSz, lpi);
return;
}
#endif // CV_SSE4_1
#endif
int length = out.length();
for (int l = 0; l < lpi; l++) {
constexpr static const auto unity = Mapper::unity;
auto beta0 = beta[l];
auto beta1 = saturate_cast<alpha_type>(unity - beta[l]);
for (int x = 0; x < length; x++) {
auto alpha0 = alpha[x];
auto alpha1 = saturate_cast<alpha_type>(unity - alpha[x]);
auto sx0 = mapsx[x];
auto sx1 = sx0 + 1;
for (int c = 0; c < numChan; c++) {
auto idx0 = numChan*sx0 + c;
auto idx1 = numChan*sx1 + c;
T tmp0 = calc(beta0, src0[l][idx0], beta1, src1[l][idx0]);
T tmp1 = calc(beta0, src0[l][idx1], beta1, src1[l][idx1]);
dst[l][numChan * x + c] = calc(alpha0, tmp0, alpha1, tmp1);
}
}
}
}
GAPI_FLUID_KERNEL(GFluidResize, cv::gapi::core::GResize, true)
{
static const int Window = 1;
static const int LPI = 4;
static const auto Kind = GFluidKernel::Kind::Resize;
constexpr static const int INTER_RESIZE_COEF_BITS = 11;
constexpr static const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;
constexpr static const short ONE = INTER_RESIZE_COEF_SCALE;
static void initScratch(const cv::GMatDesc& in,
cv::Size outSz, double fx, double fy, int /*interp*/,
cv::gapi::fluid::Buffer &scratch)
{
int outSz_w;
int outSz_h;
if (outSz.width == 0 || outSz.height == 0)
{
outSz_w = static_cast<int>(round(in.size.width * fx));
outSz_h = static_cast<int>(round(in.size.height * fy));
}
else
{
outSz_w = outSz.width;
outSz_h = outSz.height;
}
cv::Size outSize(outSz_w, outSz_h);
if (in.chan == 3)
{
initScratchLinear<uchar, Mapper, 3>(in, outSize, scratch, LPI);
}
else if (in.chan == 4)
{
initScratchLinear<uchar, Mapper, 4>(in, outSize, scratch, LPI);
}
}
static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)
{}
static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int interp,
cv::gapi::fluid::Buffer& out,
cv::gapi::fluid::Buffer& scratch) {
const int channels = in.meta().chan;
GAPI_Assert((channels == 3 || channels == 4) && (interp == cv::INTER_LINEAR));
if (channels == 3)
{
calcRowLinearC<uint8_t, Mapper, 3>(in, out, scratch);
}
else if (channels == 4)
{
calcRowLinearC<uint8_t, Mapper, 4>(in, out, scratch);
}
}
};
GAPI_FLUID_KERNEL(GFluidSqrt, cv::gapi::core::GSqrt, false)
{
static const int Window = 1;
@@ -3134,7 +2835,6 @@ cv::GKernelPackage cv::gapi::core::fluid::kernels()
,GFluidCmpNEScalar
,GFluidThreshold
,GFluidInRange
,GFluidResize
,GFluidSqrt
#if 0
,GFluidMean -- not fluid
@@ -25,6 +25,10 @@
#include "gfluidimgproc_func.hpp"
#if CV_SSE4_1
#include "gfluidcore_simd_sse41.hpp"
#endif
#include <opencv2/imgproc/hal/hal.hpp>
#include <opencv2/core/hal/intrin.hpp>
@@ -1821,6 +1825,301 @@ GAPI_FLUID_KERNEL(GFluidBayerGR2RGB, cv::gapi::imgproc::GBayerGR2RGB, false)
}
};
template<typename T, typename Mapper, int chanNum>
struct LinearScratchDesc {
using alpha_t = typename Mapper::alpha_type;
using index_t = typename Mapper::index_type;
alpha_t* alpha;
alpha_t* clone;
index_t* mapsx;
alpha_t* beta;
index_t* mapsy;
T* tmp;
LinearScratchDesc(int /*inW*/, int /*inH*/, int outW, int outH, void* data) {
alpha = reinterpret_cast<alpha_t*>(data);
clone = reinterpret_cast<alpha_t*>(alpha + outW);
mapsx = reinterpret_cast<index_t*>(clone + outW*4);
beta = reinterpret_cast<alpha_t*>(mapsx + outW);
mapsy = reinterpret_cast<index_t*>(beta + outH);
tmp = reinterpret_cast<T*> (mapsy + outH*2);
}
static int bufSize(int inW, int /*inH*/, int outW, int outH, int lpi) {
auto size = outW * sizeof(alpha_t) +
outW * sizeof(alpha_t) * 4 + // alpha clones
outW * sizeof(index_t) +
outH * sizeof(alpha_t) +
outH * sizeof(index_t) * 2 +
inW * sizeof(T) * lpi * chanNum;
return static_cast<int>(size);
}
};
static inline double invRatio(int inSz, int outSz) {
return static_cast<double>(outSz) / inSz;
}
static inline double ratio(int inSz, int outSz) {
return 1 / invRatio(inSz, outSz);
}
template<typename T, typename Mapper, int chanNum = 1>
static inline void initScratchLinear(const cv::GMatDesc& in,
const Size& outSz,
cv::gapi::fluid::Buffer& scratch,
int lpi) {
using alpha_type = typename Mapper::alpha_type;
static const auto unity = Mapper::unity;
auto inSz = in.size;
auto sbufsize = LinearScratchDesc<T, Mapper, chanNum>::bufSize(inSz.width, inSz.height, outSz.width, outSz.height, lpi);
Size scratch_size{sbufsize, 1};
cv::GMatDesc desc;
desc.chan = 1;
desc.depth = CV_8UC1;
desc.size = scratch_size;
cv::gapi::fluid::Buffer buffer(desc);
scratch = std::move(buffer);
double hRatio = ratio(in.size.width, outSz.width);
double vRatio = ratio(in.size.height, outSz.height);
LinearScratchDesc<T, Mapper, chanNum> scr(inSz.width, inSz.height, outSz.width, outSz.height, scratch.OutLineB());
auto *alpha = scr.alpha;
auto *clone = scr.clone;
auto *index = scr.mapsx;
for (int x = 0; x < outSz.width; x++) {
auto map = Mapper::map(hRatio, 0, in.size.width, x);
auto alpha0 = map.alpha0;
auto index0 = map.index0;
// TRICK:
// Algorithm takes pair of input pixels, sx0'th and sx1'th,
// and compute result as alpha0*src[sx0] + alpha1*src[sx1].
// By definition: sx1 == sx0 + 1 either sx1 == sx0, and
// alpha0 + alpha1 == unity (scaled appropriately).
// Here we modify formulas for alpha0 and sx1: by assuming
// that sx1 == sx0 + 1 always, and patching alpha0 so that
// result remains intact.
// Note that we need in.size.width >= 2, for both sx0 and
// sx0+1 were indexing pixels inside the input's width.
if (map.index1 != map.index0 + 1) {
GAPI_DbgAssert(map.index1 == map.index0);
GAPI_DbgAssert(in.size.width >= 2);
if (map.index0 < in.size.width-1) {
// sx1=sx0+1 fits inside row,
// make sure alpha0=unity and alpha1=0,
// so that result equals src[sx0]*unity
alpha0 = saturate_cast<alpha_type>(unity);
} else {
// shift sx0 to left by 1 pixel,
// and make sure that alpha0=0 and alpha1==1,
// so that result equals to src[sx0+1]*unity
alpha0 = 0;
index0--;
}
}
alpha[x] = alpha0;
index[x] = index0;
for (int l = 0; l < 4; l++) {
clone[4*x + l] = alpha0;
}
}
auto *beta = scr.beta;
auto *index_y = scr.mapsy;
for (int y = 0; y < outSz.height; y++) {
auto mapY = Mapper::map(vRatio, 0, in.size.height, y);
beta[y] = mapY.alpha0;
index_y[y] = mapY.index0;
index_y[outSz.height + y] = mapY.index1;
}
}
template<typename F, typename I>
struct MapperUnit {
F alpha0, alpha1;
I index0, index1;
};
inline static uint8_t calc(short alpha0, uint8_t src0, short alpha1, uint8_t src1) {
constexpr static const int half = 1 << 14;
return (src0 * alpha0 + src1 * alpha1 + half) >> 15;
}
struct Mapper {
constexpr static const int ONE = 1 << 15;
typedef short alpha_type;
typedef short index_type;
constexpr static const int unity = ONE;
typedef MapperUnit<short, short> Unit;
static inline Unit map(double ratio, int start, int max, int outCoord) {
float f = static_cast<float>((outCoord + 0.5) * ratio - 0.5);
int s = cvFloor(f);
f -= s;
Unit u;
u.index0 = static_cast<short>(std::max(s - start, 0));
u.index1 = static_cast<short>(((f == 0.0) || s + 1 >= max) ? s - start : s - start + 1);
u.alpha0 = saturate_cast<short>(ONE * (1.0f - f));
u.alpha1 = saturate_cast<short>(ONE * f);
return u;
}
};
template<typename T, class Mapper, int numChan>
static void calcRowLinearC(const cv::gapi::fluid::View & in,
cv::gapi::fluid::Buffer& out,
cv::gapi::fluid::Buffer& scratch) {
using alpha_type = typename Mapper::alpha_type;
auto inSz = in.meta().size;
auto outSz = out.meta().size;
auto inY = in.y();
int outY = out.y();
int lpi = out.lpi();
GAPI_DbgAssert(outY + lpi <= outSz.height);
GAPI_DbgAssert(lpi <= 4);
LinearScratchDesc<T, Mapper, numChan> scr(inSz.width, inSz.height, outSz.width, outSz.height, scratch.OutLineB());
const auto *alpha = scr.alpha;
const auto *mapsx = scr.mapsx;
const auto *beta_0 = scr.beta;
const auto *mapsy = scr.mapsy;
const auto *beta = beta_0 + outY;
const T *src0[4];
const T *src1[4];
T* dst[4];
for (int l = 0; l < lpi; l++) {
auto index0 = mapsy[outY + l] - inY;
auto index1 = mapsy[outSz.height + outY + l] - inY;
src0[l] = in.InLine<const T>(index0);
src1[l] = in.InLine<const T>(index1);
dst[l] = out.OutLine<T>(l);
}
#if 0 // Disabling SSE4.1 path due to Valgrind issues: https://github.com/opencv/opencv/issues/21097
#if CV_SSE4_1
const auto* clone = scr.clone;
auto* tmp = scr.tmp;
if (inSz.width >= 16 && outSz.width >= 16)
{
sse42::calcRowLinear_8UC_Impl_<numChan>(reinterpret_cast<uint8_t**>(dst),
reinterpret_cast<const uint8_t**>(src0),
reinterpret_cast<const uint8_t**>(src1),
reinterpret_cast<const short*>(alpha),
reinterpret_cast<const short*>(clone),
reinterpret_cast<const short*>(mapsx),
reinterpret_cast<const short*>(beta),
reinterpret_cast<uint8_t*>(tmp),
inSz, outSz, lpi);
return;
}
#endif // CV_SSE4_1
#endif
int length = out.length();
for (int l = 0; l < lpi; l++) {
constexpr static const auto unity = Mapper::unity;
auto beta0 = beta[l];
auto beta1 = saturate_cast<alpha_type>(unity - beta[l]);
for (int x = 0; x < length; x++) {
auto alpha0 = alpha[x];
auto alpha1 = saturate_cast<alpha_type>(unity - alpha[x]);
auto sx0 = mapsx[x];
auto sx1 = sx0 + 1;
for (int c = 0; c < numChan; c++) {
auto idx0 = numChan*sx0 + c;
auto idx1 = numChan*sx1 + c;
T tmp0 = calc(beta0, src0[l][idx0], beta1, src1[l][idx0]);
T tmp1 = calc(beta0, src0[l][idx1], beta1, src1[l][idx1]);
dst[l][numChan * x + c] = calc(alpha0, tmp0, alpha1, tmp1);
}
}
}
}
GAPI_FLUID_KERNEL(GFluidResize, cv::gapi::imgproc::GResize, true)
{
static const int Window = 1;
static const int LPI = 4;
static const auto Kind = GFluidKernel::Kind::Resize;
constexpr static const int INTER_RESIZE_COEF_BITS = 11;
constexpr static const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;
constexpr static const short ONE = INTER_RESIZE_COEF_SCALE;
static void initScratch(const cv::GMatDesc& in,
cv::Size outSz, double fx, double fy, int /*interp*/,
cv::gapi::fluid::Buffer &scratch)
{
int outSz_w;
int outSz_h;
if (outSz.width == 0 || outSz.height == 0)
{
outSz_w = static_cast<int>(round(in.size.width * fx));
outSz_h = static_cast<int>(round(in.size.height * fy));
}
else
{
outSz_w = outSz.width;
outSz_h = outSz.height;
}
cv::Size outSize(outSz_w, outSz_h);
if (in.chan == 3)
{
initScratchLinear<uchar, Mapper, 3>(in, outSize, scratch, LPI);
}
else if (in.chan == 4)
{
initScratchLinear<uchar, Mapper, 4>(in, outSize, scratch, LPI);
}
}
static void resetScratch(cv::gapi::fluid::Buffer& /*scratch*/)
{}
static void run(const cv::gapi::fluid::View& in, cv::Size /*sz*/, double /*fx*/, double /*fy*/, int interp,
cv::gapi::fluid::Buffer& out,
cv::gapi::fluid::Buffer& scratch) {
const int channels = in.meta().chan;
GAPI_Assert((channels == 3 || channels == 4) && (interp == cv::INTER_LINEAR));
if (channels == 3)
{
calcRowLinearC<uint8_t, Mapper, 3>(in, out, scratch);
}
else if (channels == 4)
{
calcRowLinearC<uint8_t, Mapper, 4>(in, out, scratch);
}
}
};
} // namespace fluid
} // namespace gapi
} // namespace cv
@@ -1831,6 +2130,7 @@ cv::GKernelPackage cv::gapi::imgproc::fluid::kernels()
return cv::gapi::kernels
< GFluidBGR2Gray
, GFluidResize
, GFluidRGB2Gray
, GFluidRGB2GrayCustom
, GFluidRGB2YUV
@@ -458,14 +458,6 @@ GAPI_OCL_KERNEL(GOCLMerge4, cv::gapi::core::GMerge4)
}
};
GAPI_OCL_KERNEL(GOCLResize, cv::gapi::core::GResize)
{
static void run(const cv::UMat& in, cv::Size sz, double fx, double fy, int interp, cv::UMat &out)
{
cv::resize(in, out, sz, fx, fy, interp);
}
};
GAPI_OCL_KERNEL(GOCLRemap, cv::gapi::core::GRemap)
{
static void run(const cv::UMat& in, const cv::Mat& x, const cv::Mat& y, int a, int b, cv::Scalar s, cv::UMat& out)
@@ -585,7 +577,6 @@ cv::GKernelPackage cv::gapi::core::ocl::kernels()
, GOCLInRange
, GOCLSplit3
, GOCLSplit4
, GOCLResize
, GOCLMerge3
, GOCLMerge4
, GOCLRemap
@@ -11,6 +11,13 @@
#include <opencv2/gapi/ocl/imgproc.hpp>
#include "backends/ocl/goclimgproc.hpp"
GAPI_OCL_KERNEL(GOCLResize, cv::gapi::imgproc::GResize)
{
static void run(const cv::UMat& in, cv::Size sz, double fx, double fy, int interp, cv::UMat &out)
{
cv::resize(in, out, sz, fx, fy, interp);
}
};
GAPI_OCL_KERNEL(GOCLSepFilter, cv::gapi::imgproc::GSepFilter)
{
@@ -270,6 +277,7 @@ cv::GKernelPackage cv::gapi::imgproc::ocl::kernels()
{
static auto pkg = cv::gapi::kernels
< GOCLFilter2D
, GOCLResize
, GOCLSepFilter
, GOCLBoxFilter
, GOCLBlur