mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00

G-API GPU-OpenCL backend (#13008) * gpu/ocl backend core * accuracy tests added and adjusted + license headers * GPU perf. tests added; almost all adjusted to pass * all tests adjusted and passed - ready for pull request * missing license headers * fix warning (workaround RGB2Gray) * fix c++ magic * precompiled header * white spaces * try to fix warning and blur test * try to fix Blur perf tests * more alignments with the latest cpu backend * more gapi tests refactoring + 1 more UB issue fix + more informative tolerance exceed reports * white space fix * try workaround for SumTest * GAPI_EXPORTS instead CV_EXPORTS
278 lines
8.9 KiB
C++
278 lines
8.9 KiB
C++
// This file is part of OpenCV project.
|
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
|
// of this distribution and at http://opencv.org/license.html.
|
|
//
|
|
// Copyright (C) 2018 Intel Corporation
|
|
|
|
|
|
#include "precomp.hpp"
|
|
|
|
#include "opencv2/gapi/imgproc.hpp"
|
|
#include "opencv2/gapi/gpu/imgproc.hpp"
|
|
#include "backends/gpu/ggpuimgproc.hpp"
|
|
|
|
|
|
GAPI_GPU_KERNEL(GGPUSepFilter, cv::gapi::imgproc::GSepFilter)
|
|
{
|
|
static void run(const cv::UMat& in, int ddepth, const cv::Mat& kernX, const cv::Mat& kernY, const cv::Point& anchor, const cv::Scalar& delta,
|
|
int border, const cv::Scalar& bordVal, cv::UMat &out)
|
|
{
|
|
if( border == cv::BORDER_CONSTANT )
|
|
{
|
|
cv::UMat temp_in;
|
|
int width_add = (kernY.cols - 1) / 2;
|
|
int height_add = (kernX.rows - 1) / 2;
|
|
cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, border, bordVal);
|
|
cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
|
|
cv::sepFilter2D(temp_in(rect), out, ddepth, kernX, kernY, anchor, delta.val[0], border);
|
|
}
|
|
else
|
|
cv::sepFilter2D(in, out, ddepth, kernX, kernY, anchor, delta.val[0], border);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUBoxFilter, cv::gapi::imgproc::GBoxFilter)
|
|
{
|
|
static void run(const cv::UMat& in, int ddepth, const cv::Size& ksize, const cv::Point& anchor, bool normalize, int borderType, const cv::Scalar& bordVal, cv::UMat &out)
|
|
{
|
|
if( borderType == cv::BORDER_CONSTANT )
|
|
{
|
|
cv::UMat temp_in;
|
|
int width_add = (ksize.width - 1) / 2;
|
|
int height_add = (ksize.height - 1) / 2;
|
|
cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, borderType, bordVal);
|
|
cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
|
|
cv::boxFilter(temp_in(rect), out, ddepth, ksize, anchor, normalize, borderType);
|
|
}
|
|
else
|
|
cv::boxFilter(in, out, ddepth, ksize, anchor, normalize, borderType);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUBlur, cv::gapi::imgproc::GBlur)
|
|
{
|
|
static void run(const cv::UMat& in, const cv::Size& ksize, const cv::Point& anchor, int borderType, const cv::Scalar& bordVal, cv::UMat &out)
|
|
{
|
|
if( borderType == cv::BORDER_CONSTANT )
|
|
{
|
|
cv::UMat temp_in;
|
|
int width_add = (ksize.width - 1) / 2;
|
|
int height_add = (ksize.height - 1) / 2;
|
|
cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, borderType, bordVal);
|
|
cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
|
|
cv::blur(temp_in(rect), out, ksize, anchor, borderType);
|
|
}
|
|
else
|
|
cv::blur(in, out, ksize, anchor, borderType);
|
|
}
|
|
};
|
|
|
|
|
|
GAPI_GPU_KERNEL(GGPUFilter2D, cv::gapi::imgproc::GFilter2D)
|
|
{
|
|
static void run(const cv::UMat& in, int ddepth, const cv::Mat& k, const cv::Point& anchor, const cv::Scalar& delta, int border,
|
|
const cv::Scalar& bordVal, cv::UMat &out)
|
|
{
|
|
if( border == cv::BORDER_CONSTANT )
|
|
{
|
|
cv::UMat temp_in;
|
|
int width_add = (k.cols - 1) / 2;
|
|
int height_add = (k.rows - 1) / 2;
|
|
cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, border, bordVal );
|
|
cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
|
|
cv::filter2D(temp_in(rect), out, ddepth, k, anchor, delta.val[0], border);
|
|
}
|
|
else
|
|
cv::filter2D(in, out, ddepth, k, anchor, delta.val[0], border);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUGaussBlur, cv::gapi::imgproc::GGaussBlur)
|
|
{
|
|
static void run(const cv::UMat& in, const cv::Size& ksize, double sigmaX, double sigmaY, int borderType, const cv::Scalar& bordVal, cv::UMat &out)
|
|
{
|
|
if( borderType == cv::BORDER_CONSTANT )
|
|
{
|
|
cv::UMat temp_in;
|
|
int width_add = (ksize.width - 1) / 2;
|
|
int height_add = (ksize.height - 1) / 2;
|
|
cv::copyMakeBorder(in, temp_in, height_add, height_add, width_add, width_add, borderType, bordVal );
|
|
cv::Rect rect = cv::Rect(height_add, width_add, in.cols, in.rows);
|
|
cv::GaussianBlur(temp_in(rect), out, ksize, sigmaX, sigmaY, borderType);
|
|
}
|
|
else
|
|
cv::GaussianBlur(in, out, ksize, sigmaX, sigmaY, borderType);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUMedianBlur, cv::gapi::imgproc::GMedianBlur)
|
|
{
|
|
static void run(const cv::UMat& in, int ksize, cv::UMat &out)
|
|
{
|
|
cv::medianBlur(in, out, ksize);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUErode, cv::gapi::imgproc::GErode)
|
|
{
|
|
static void run(const cv::UMat& in, const cv::Mat& kernel, const cv::Point& anchor, int iterations, int borderType, const cv::Scalar& borderValue, cv::UMat &out)
|
|
{
|
|
cv::erode(in, out, kernel, anchor, iterations, borderType, borderValue);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUDilate, cv::gapi::imgproc::GDilate)
|
|
{
|
|
static void run(const cv::UMat& in, const cv::Mat& kernel, const cv::Point& anchor, int iterations, int borderType, const cv::Scalar& borderValue, cv::UMat &out)
|
|
{
|
|
cv::dilate(in, out, kernel, anchor, iterations, borderType, borderValue);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUSobel, cv::gapi::imgproc::GSobel)
|
|
{
|
|
static void run(const cv::UMat& in, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType,
|
|
const cv::Scalar& bordVal, cv::UMat &out)
|
|
{
|
|
if( borderType == cv::BORDER_CONSTANT )
|
|
{
|
|
cv::UMat temp_in;
|
|
int add = (ksize - 1) / 2;
|
|
cv::copyMakeBorder(in, temp_in, add, add, add, add, borderType, bordVal );
|
|
cv::Rect rect = cv::Rect(add, add, in.cols, in.rows);
|
|
cv::Sobel(temp_in(rect), out, ddepth, dx, dy, ksize, scale, delta, borderType);
|
|
}
|
|
else
|
|
cv::Sobel(in, out, ddepth, dx, dy, ksize, scale, delta, borderType);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUEqualizeHist, cv::gapi::imgproc::GEqHist)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::equalizeHist(in, out);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUCanny, cv::gapi::imgproc::GCanny)
|
|
{
|
|
static void run(const cv::UMat& in, double thr1, double thr2, int apSize, bool l2gradient, cv::UMat &out)
|
|
{
|
|
cv::Canny(in, out, thr1, thr2, apSize, l2gradient);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPURGB2YUV, cv::gapi::imgproc::GRGB2YUV)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_RGB2YUV);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUYUV2RGB, cv::gapi::imgproc::GYUV2RGB)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_YUV2RGB);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPURGB2Lab, cv::gapi::imgproc::GRGB2Lab)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_RGB2Lab);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUBGR2LUV, cv::gapi::imgproc::GBGR2LUV)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_BGR2Luv);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUBGR2YUV, cv::gapi::imgproc::GBGR2YUV)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_BGR2YUV);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPULUV2BGR, cv::gapi::imgproc::GLUV2BGR)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_Luv2BGR);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUYUV2BGR, cv::gapi::imgproc::GYUV2BGR)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_YUV2BGR);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPURGB2Gray, cv::gapi::imgproc::GRGB2Gray)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_RGB2GRAY);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPUBGR2Gray, cv::gapi::imgproc::GBGR2Gray)
|
|
{
|
|
static void run(const cv::UMat& in, cv::UMat &out)
|
|
{
|
|
cv::cvtColor(in, out, cv::COLOR_BGR2GRAY);
|
|
}
|
|
};
|
|
|
|
GAPI_GPU_KERNEL(GGPURGB2GrayCustom, cv::gapi::imgproc::GRGB2GrayCustom)
|
|
{
|
|
//TODO: avoid copy
|
|
static void run(const cv::UMat& in, float rY, float bY, float gY, cv::UMat &out)
|
|
{
|
|
cv::Mat planes[3];
|
|
cv::split(in.getMat(cv::ACCESS_READ), planes);
|
|
cv::Mat tmp_out = (planes[0]*rY + planes[1]*bY + planes[2]*gY);
|
|
tmp_out.copyTo(out);
|
|
}
|
|
};
|
|
|
|
|
|
cv::gapi::GKernelPackage cv::gapi::imgproc::gpu::kernels()
|
|
{
|
|
static auto pkg = cv::gapi::kernels
|
|
< GGPUFilter2D
|
|
, GGPUSepFilter
|
|
, GGPUBoxFilter
|
|
, GGPUBlur
|
|
, GGPUGaussBlur
|
|
, GGPUMedianBlur
|
|
, GGPUErode
|
|
, GGPUDilate
|
|
, GGPUSobel
|
|
, GGPUCanny
|
|
, GGPUEqualizeHist
|
|
, GGPURGB2YUV
|
|
, GGPUYUV2RGB
|
|
, GGPURGB2Lab
|
|
, GGPUBGR2LUV
|
|
, GGPUBGR2YUV
|
|
, GGPUYUV2BGR
|
|
, GGPULUV2BGR
|
|
, GGPUBGR2Gray
|
|
, GGPURGB2Gray
|
|
, GGPURGB2GrayCustom
|
|
>();
|
|
return pkg;
|
|
}
|