#define OPENCV_GAPI_CORE_HPP
#include <math.h>
-
#include <utility> // std::tuple
#include <opencv2/imgproc.hpp>
+#include <opencv2/gapi/imgproc.hpp>
#include <opencv2/gapi/gmat.hpp>
#include <opencv2/gapi/gscalar.hpp>
* Core module functionality.
*/
namespace core {
+ using GResize = cv::gapi::imgproc::GResize;
+ using GResizeP = cv::gapi::imgproc::GResizeP;
+
using GMat2 = std::tuple<GMat,GMat>;
using GMat3 = std::tuple<GMat,GMat,GMat>; // FIXME: how to avoid this?
using GMat4 = std::tuple<GMat,GMat,GMat,GMat>;
}
};
- G_TYPED_KERNEL(GMulC, <GMat(GMat, GScalar, int)>, "org.opencv.core.math.mulC"){
+ G_TYPED_KERNEL(GMulC, <GMat(GMat, GScalar, int)>, "org.opencv.core.math.mulC") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc, int ddepth) {
return a.withDepth(ddepth);
}
}
};
- G_TYPED_KERNEL(GCmpGTScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpGTScalar"){
+ G_TYPED_KERNEL(GCmpGTScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpGTScalar") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc) {
return a.withDepth(CV_8U);
}
};
- G_TYPED_KERNEL(GCmpGEScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpGEScalar"){
+ G_TYPED_KERNEL(GCmpGEScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpGEScalar") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc) {
return a.withDepth(CV_8U);
}
};
- G_TYPED_KERNEL(GCmpLEScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpLEScalar"){
+ G_TYPED_KERNEL(GCmpLEScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpLEScalar") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc) {
return a.withDepth(CV_8U);
}
};
- G_TYPED_KERNEL(GCmpLTScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpLTScalar"){
+ G_TYPED_KERNEL(GCmpLTScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpLTScalar") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc) {
return a.withDepth(CV_8U);
}
};
- G_TYPED_KERNEL(GCmpEQScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpEQScalar"){
+ G_TYPED_KERNEL(GCmpEQScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpEQScalar") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc) {
return a.withDepth(CV_8U);
}
};
- G_TYPED_KERNEL(GCmpNEScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpNEScalar"){
+ G_TYPED_KERNEL(GCmpNEScalar, <GMat(GMat, GScalar)>, "org.opencv.core.pixelwise.compare.cmpNEScalar") {
static GMatDesc outMeta(GMatDesc a, GScalarDesc) {
return a.withDepth(CV_8U);
}
}
};
- G_TYPED_KERNEL(GResize, <GMat(GMat,Size,double,double,int)>, "org.opencv.core.transform.resize") {
- static GMatDesc outMeta(GMatDesc in, Size sz, double fx, double fy, int /*interp*/) {
- if (sz.width != 0 && sz.height != 0)
- {
- return in.withSize(sz);
- }
- else
- {
- int outSz_w = static_cast<int>(round(in.size.width * fx));
- int outSz_h = static_cast<int>(round(in.size.height * fy));
- GAPI_Assert(outSz_w > 0 && outSz_h > 0);
- return in.withSize(Size(outSz_w, outSz_h));
- }
- }
- };
-
- G_TYPED_KERNEL(GResizeP, <GMatP(GMatP,Size,int)>, "org.opencv.core.transform.resizeP") {
- static GMatDesc outMeta(GMatDesc in, Size sz, int interp) {
- GAPI_Assert(in.depth == CV_8U);
- GAPI_Assert(in.chan == 3);
- GAPI_Assert(in.planar);
- GAPI_Assert(interp == cv::INTER_LINEAR);
- return in.withSize(sz);
- }
- };
-
G_TYPED_KERNEL(GMerge3, <GMat(GMat,GMat,GMat)>, "org.opencv.core.transform.merge3") {
static GMatDesc outMeta(GMatDesc in, GMatDesc, GMatDesc) {
// Preserve depth and add channel component
//! @addtogroup gapi_transform
//! @{
-/** @brief Resizes an image.
-
-The function resizes the image src down to or up to the specified size.
-
-Output image size will have the size dsize (when dsize is non-zero) or the size computed from
-src.size(), fx, and fy; the depth of output is the same as of src.
-
-If you want to resize src so that it fits the pre-created dst,
-you may call the function as follows:
-@code
- // explicitly specify dsize=dst.size(); fx and fy will be computed from that.
- resize(src, dst, dst.size(), 0, 0, interpolation);
-@endcode
-If you want to decimate the image by factor of 2 in each direction, you can call the function this
-way:
-@code
- // specify fx and fy and let the function compute the destination image size.
- resize(src, dst, Size(), 0.5, 0.5, interpolation);
-@endcode
-To shrink an image, it will generally look best with cv::INTER_AREA interpolation, whereas to
-enlarge an image, it will generally look best with cv::INTER_CUBIC (slow) or cv::INTER_LINEAR
-(faster but still looks OK).
-
-@note Function textual ID is "org.opencv.core.transform.resize"
-
-@param src input image.
-@param dsize output image size; if it equals zero, it is computed as:
- \f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f]
- Either dsize or both fx and fy must be non-zero.
-@param fx scale factor along the horizontal axis; when it equals 0, it is computed as
-\f[\texttt{(double)dsize.width/src.cols}\f]
-@param fy scale factor along the vertical axis; when it equals 0, it is computed as
-\f[\texttt{(double)dsize.height/src.rows}\f]
-@param interpolation interpolation method, see cv::InterpolationFlags
-
-@sa warpAffine, warpPerspective, remap, resizeP
- */
-GAPI_EXPORTS_W GMat resize(const GMat& src, const Size& dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);
-
-/** @brief Resizes a planar image.
-
-The function resizes the image src down to or up to the specified size.
-Planar image memory layout is three planes laying in the memory contiguously,
-so the image height should be plane_height*plane_number, image type is @ref CV_8UC1.
-
-Output image size will have the size dsize, the depth of output is the same as of src.
-
-@note Function textual ID is "org.opencv.core.transform.resizeP"
-
-@param src input image, must be of @ref CV_8UC1 type;
-@param dsize output image size;
-@param interpolation interpolation method, only cv::INTER_LINEAR is supported at the moment
-
-@sa warpAffine, warpPerspective, remap, resize
- */
-GAPI_EXPORTS GMatP resizeP(const GMatP& src, const Size& dsize, int interpolation = cv::INTER_LINEAR);
-
/** @brief Creates one 4-channel matrix out of 4 single-channel ones.
The function merges several matrices to make a single multi-channel matrix. That is, each
@defgroup gapi_colorconvert Graph API: Converting image from one color space to another
@defgroup gapi_feature Graph API: Image Feature Detection
@defgroup gapi_shape Graph API: Image Structural Analysis and Shape Descriptors
+ @defgroup gapi_transform Graph API: Image and channel composition functions
@}
*/
using GMat3 = std::tuple<GMat,GMat,GMat>; // FIXME: how to avoid this?
using GFindContoursOutput = std::tuple<GArray<GArray<Point>>,GArray<Vec4i>>;
- G_TYPED_KERNEL(GFilter2D, <GMat(GMat,int,Mat,Point,Scalar,int,Scalar)>,"org.opencv.imgproc.filters.filter2D") {
+ G_TYPED_KERNEL(GFilter2D, <GMat(GMat,int,Mat,Point,Scalar,int,Scalar)>, "org.opencv.imgproc.filters.filter2D") {
static GMatDesc outMeta(GMatDesc in, int ddepth, Mat, Point, Scalar, int, Scalar) {
return in.withDepth(ddepth);
}
}
};
- G_TYPED_KERNEL(GBlur, <GMat(GMat,Size,Point,int,Scalar)>, "org.opencv.imgproc.filters.blur"){
+ G_TYPED_KERNEL(GBlur, <GMat(GMat,Size,Point,int,Scalar)>, "org.opencv.imgproc.filters.blur") {
static GMatDesc outMeta(GMatDesc in, Size, Point, int, Scalar) {
return in;
}
}
};
- G_TYPED_KERNEL(GEqHist, <GMat(GMat)>, "org.opencv.imgproc.equalizeHist"){
+ G_TYPED_KERNEL(GEqHist, <GMat(GMat)>, "org.opencv.imgproc.equalizeHist") {
static GMatDesc outMeta(GMatDesc in) {
return in.withType(CV_8U, 1);
}
};
- G_TYPED_KERNEL(GCanny, <GMat(GMat,double,double,int,bool)>, "org.opencv.imgproc.feature.canny"){
+ G_TYPED_KERNEL(GCanny, <GMat(GMat,double,double,int,bool)>, "org.opencv.imgproc.feature.canny") {
static GMatDesc outMeta(GMatDesc in, double, double, int, bool) {
return in.withType(CV_8U, 1);
}
}
};
+ G_TYPED_KERNEL(GResize, <GMat(GMat,Size,double,double,int)>, "org.opencv.imgproc.transform.resize") {
+ static GMatDesc outMeta(GMatDesc in, Size sz, double fx, double fy, int /*interp*/) {
+ if (sz.width != 0 && sz.height != 0)
+ {
+ return in.withSize(sz);
+ }
+ else
+ {
+ int outSz_w = static_cast<int>(round(in.size.width * fx));
+ int outSz_h = static_cast<int>(round(in.size.height * fy));
+ GAPI_Assert(outSz_w > 0 && outSz_h > 0);
+ return in.withSize(Size(outSz_w, outSz_h));
+ }
+ }
+ };
+
+ G_TYPED_KERNEL(GResizeP, <GMatP(GMatP,Size,int)>, "org.opencv.imgproc.transform.resizeP") {
+ static GMatDesc outMeta(GMatDesc in, Size sz, int interp) {
+ GAPI_Assert(in.depth == CV_8U);
+ GAPI_Assert(in.chan == 3);
+ GAPI_Assert(in.planar);
+ GAPI_Assert(interp == cv::INTER_LINEAR);
+ return in.withSize(sz);
+ }
+ };
+
} //namespace imgproc
//! @addtogroup gapi_filters
GAPI_EXPORTS GMatP NV12toBGRp(const GMat &src_y, const GMat &src_uv);
//! @} gapi_colorconvert
+//! @addtogroup gapi_transform
+//! @{
+/** @brief Resizes an image.
+
+The function resizes the image src down to or up to the specified size.
+
+Output image size will have the size dsize (when dsize is non-zero) or the size computed from
+src.size(), fx, and fy; the depth of output is the same as of src.
+
+If you want to resize src so that it fits the pre-created dst,
+you may call the function as follows:
+@code
+ // explicitly specify dsize=dst.size(); fx and fy will be computed from that.
+ resize(src, dst, dst.size(), 0, 0, interpolation);
+@endcode
+If you want to decimate the image by factor of 2 in each direction, you can call the function this
+way:
+@code
+ // specify fx and fy and let the function compute the destination image size.
+ resize(src, dst, Size(), 0.5, 0.5, interpolation);
+@endcode
+To shrink an image, it will generally look best with cv::INTER_AREA interpolation, whereas to
+enlarge an image, it will generally look best with cv::INTER_CUBIC (slow) or cv::INTER_LINEAR
+(faster but still looks OK).
+
+@note Function textual ID is "org.opencv.imgproc.transform.resize"
+
+@param src input image.
+@param dsize output image size; if it equals zero, it is computed as:
+ \f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f]
+ Either dsize or both fx and fy must be non-zero.
+@param fx scale factor along the horizontal axis; when it equals 0, it is computed as
+\f[\texttt{(double)dsize.width/src.cols}\f]
+@param fy scale factor along the vertical axis; when it equals 0, it is computed as
+\f[\texttt{(double)dsize.height/src.rows}\f]
+@param interpolation interpolation method, see cv::InterpolationFlags
+
+@sa warpAffine, warpPerspective, remap, resizeP
+ */
+GAPI_EXPORTS_W GMat resize(const GMat& src, const Size& dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);
+
+/** @brief Resizes a planar image.
+
+The function resizes the image src down to or up to the specified size.
+Planar image memory layout is three planes laying in the memory contiguously,
+so the image height should be plane_height*plane_number, image type is @ref CV_8UC1.
+
+Output image size will have the size dsize, the depth of output is the same as of src.
+
+@note Function textual ID is "org.opencv.imgproc.transform.resizeP"
+
+@param src input image, must be of @ref CV_8UC1 type;
+@param dsize output image size;
+@param interpolation interpolation method, only cv::INTER_LINEAR is supported at the moment
+
+@sa warpAffine, warpPerspective, remap, resize
+ */
+GAPI_EXPORTS GMatP resizeP(const GMatP& src, const Size& dsize, int interpolation = cv::INTER_LINEAR);
+
+//! @} gapi_transform
} //namespace gapi
} //namespace cv
return core::GMerge4::on(src1, src2, src3, src4);
}
-GMat resize(const GMat& src, const Size& dsize, double fx, double fy, int interpolation)
-{
- return core::GResize::on(src, dsize, fx, fy, interpolation);
-}
-
-GMatP resizeP(const GMatP& src, const Size& dsize, int interpolation)
-{
- return core::GResizeP::on(src, dsize, interpolation);
-}
-
GMat remap(const GMat& src, const Mat& map1, const Mat& map2,
int interpolation, int borderMode,
const Scalar& borderValue)
namespace cv { namespace gapi {
+GMat resize(const GMat& src, const Size& dsize, double fx, double fy, int interpolation)
+{
+ return imgproc::GResize::on(src, dsize, fx, fy, interpolation);
+}
+
+GMatP resizeP(const GMatP& src, const Size& dsize, int interpolation)
+{
+ return imgproc::GResizeP::on(src, dsize, interpolation);
+}
+
GMat sepFilter(const GMat& src, int ddepth, const Mat& kernelX, const Mat& kernelY, const Point& anchor,
const Scalar& delta, int borderType, const Scalar& borderVal)
{
}
};
-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)
, GCPUInRange
, GCPUSplit3
, GCPUSplit4
- , GCPUResize
- , GCPUResizeP
, GCPUMerge3
, GCPUMerge4
, GCPURemap
}
}
+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,
{
static auto pkg = cv::gapi::kernels
< GCPUFilter2D
+ , GCPUResize
+ , GCPUResizeP
, GCPUSepFilter
, GCPUBoxFilter
, GCPUBlur
#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"
}
};
-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;
,GFluidCmpNEScalar
,GFluidThreshold
,GFluidInRange
- ,GFluidResize
,GFluidSqrt
#if 0
,GFluidMean -- not fluid
#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>
}
};
+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
return cv::gapi::kernels
< GFluidBGR2Gray
+ , GFluidResize
, GFluidRGB2Gray
, GFluidRGB2GrayCustom
, GFluidRGB2YUV
}
};
-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)
, GOCLInRange
, GOCLSplit3
, GOCLSplit4
- , GOCLResize
, GOCLMerge3
, GOCLMerge4
, GOCLRemap
#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)
{
{
static auto pkg = cv::gapi::kernels
< GOCLFilter2D
+ , GOCLResize
, GOCLSepFilter
, GOCLBoxFilter
, GOCLBlur
GAPI_TEST_FIXTURE(InRangeTest, initMatrixRandU, <>, 0)
GAPI_TEST_FIXTURE(Split3Test, initMatrixRandU, <>, 0)
GAPI_TEST_FIXTURE(Split4Test, initMatrixRandU, <>, 0)
-GAPI_TEST_FIXTURE(ResizeTest, initNothing, FIXTURE_API(CompareMats,int,cv::Size), 3,
- cmpF, interp, sz_out)
-GAPI_TEST_FIXTURE(ResizePTest, initNothing, FIXTURE_API(CompareMats,int,cv::Size), 3,
- cmpF, interp, sz_out)
-GAPI_TEST_FIXTURE(ResizeTestFxFy, initNothing, FIXTURE_API(CompareMats,int,double,double), 4,
- cmpF, interp, fx, fy)
GAPI_TEST_FIXTURE(Merge3Test, initMatsRandU, <>, 0)
GAPI_TEST_FIXTURE(Merge4Test, initMatsRandU, <>, 0)
GAPI_TEST_FIXTURE(RemapTest, initMatrixRandU, <>, 0)
}
}
-static void ResizeAccuracyTest(const CompareMats& cmpF, int type, int interp, cv::Size sz_in,
- cv::Size sz_out, double fx, double fy, cv::GCompileArgs&& compile_args)
-{
- cv::Mat in_mat1 (sz_in, type );
- cv::Scalar mean = cv::Scalar::all(127);
- cv::Scalar stddev = cv::Scalar::all(40.f);
-
- cv::randn(in_mat1, mean, stddev);
-
- auto out_mat_sz = sz_out.area() == 0 ? cv::Size(saturate_cast<int>(sz_in.width *fx),
- saturate_cast<int>(sz_in.height*fy))
- : sz_out;
- cv::Mat out_mat(out_mat_sz, type);
- cv::Mat out_mat_ocv(out_mat_sz, type);
-
- // G-API code //////////////////////////////////////////////////////////////
- cv::GMat in;
- auto out = cv::gapi::resize(in, sz_out, fx, fy, interp);
-
- cv::GComputation c(in, out);
- c.apply(in_mat1, out_mat, std::move(compile_args));
- // OpenCV code /////////////////////////////////////////////////////////////
- {
- cv::resize(in_mat1, out_mat_ocv, sz_out, fx, fy, interp);
- }
- // Comparison //////////////////////////////////////////////////////////////
- {
- EXPECT_TRUE(cmpF(out_mat, out_mat_ocv));
- }
-}
-
-TEST_P(ResizeTest, AccuracyTest)
-{
- ResizeAccuracyTest(cmpF, type, interp, sz, sz_out, 0.0, 0.0, getCompileArgs());
-}
-
-TEST_P(ResizeTestFxFy, AccuracyTest)
-{
- ResizeAccuracyTest(cmpF, type, interp, sz, cv::Size{0, 0}, fx, fy, getCompileArgs());
-}
-
-TEST_P(ResizePTest, AccuracyTest)
-{
- constexpr int planeNum = 3;
- cv::Size sz_in_p {sz.width, sz.height*planeNum};
- cv::Size sz_out_p{sz_out.width, sz_out.height*planeNum};
-
- cv::Mat in_mat(sz_in_p, CV_8UC1);
- cv::randn(in_mat, cv::Scalar::all(127.0f), cv::Scalar::all(40.f));
-
- cv::Mat out_mat (sz_out_p, CV_8UC1);
- cv::Mat out_mat_ocv_p(sz_out_p, CV_8UC1);
-
- cv::GMatP in;
- auto out = cv::gapi::resizeP(in, sz_out, interp);
- cv::GComputation c(cv::GIn(in), cv::GOut(out));
-
- c.compile(cv::descr_of(in_mat).asPlanar(planeNum), getCompileArgs())
- (cv::gin(in_mat), cv::gout(out_mat));
-
- for (int i = 0; i < planeNum; i++) {
- const cv::Mat in_mat_roi = in_mat(cv::Rect(0, i*sz.height, sz.width, sz.height));
- cv::Mat out_mat_roi = out_mat_ocv_p(cv::Rect(0, i*sz_out.height, sz_out.width, sz_out.height));
- cv::resize(in_mat_roi, out_mat_roi, sz_out, 0, 0, interp);
- }
-
- // Comparison //////////////////////////////////////////////////////////////
- {
- EXPECT_TRUE(cmpF(out_mat, out_mat_ocv_p));
- }
-}
-
TEST_P(Merge3Test, AccuracyTest)
{
cv::Mat in_mat3(sz, type);
GAPI_TEST_FIXTURE(RGB2HSVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(BayerGR2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2YUV422Test, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
+GAPI_TEST_FIXTURE(ResizeTest, initNothing, FIXTURE_API(CompareMats,int,cv::Size), 3,
+ cmpF, interp, sz_out)
+GAPI_TEST_FIXTURE(ResizePTest, initNothing, FIXTURE_API(CompareMats,int,cv::Size), 3,
+ cmpF, interp, sz_out)
+GAPI_TEST_FIXTURE(ResizeTestFxFy, initNothing, FIXTURE_API(CompareMats,int,double,double), 4,
+ cmpF, interp, fx, fy)
} // opencv_test
#endif //OPENCV_GAPI_IMGPROC_TESTS_HPP
EXPECT_EQ(sz, out_mat_gapi.size());
}
}
+
+static void ResizeAccuracyTest(const CompareMats& cmpF, int type, int interp, cv::Size sz_in,
+ cv::Size sz_out, double fx, double fy, cv::GCompileArgs&& compile_args)
+{
+ cv::Mat in_mat1 (sz_in, type );
+ cv::Scalar mean = cv::Scalar::all(127);
+ cv::Scalar stddev = cv::Scalar::all(40.f);
+
+ cv::randn(in_mat1, mean, stddev);
+
+ auto out_mat_sz = sz_out.area() == 0 ? cv::Size(saturate_cast<int>(sz_in.width *fx),
+ saturate_cast<int>(sz_in.height*fy))
+ : sz_out;
+ cv::Mat out_mat(out_mat_sz, type);
+ cv::Mat out_mat_ocv(out_mat_sz, type);
+
+ // G-API code //////////////////////////////////////////////////////////////
+ cv::GMat in;
+ auto out = cv::gapi::resize(in, sz_out, fx, fy, interp);
+
+ cv::GComputation c(in, out);
+ c.apply(in_mat1, out_mat, std::move(compile_args));
+ // OpenCV code /////////////////////////////////////////////////////////////
+ {
+ cv::resize(in_mat1, out_mat_ocv, sz_out, fx, fy, interp);
+ }
+ // Comparison //////////////////////////////////////////////////////////////
+ {
+ EXPECT_TRUE(cmpF(out_mat, out_mat_ocv));
+ }
+}
+
+TEST_P(ResizeTest, AccuracyTest)
+{
+ ResizeAccuracyTest(cmpF, type, interp, sz, sz_out, 0.0, 0.0, getCompileArgs());
+}
+
+TEST_P(ResizeTestFxFy, AccuracyTest)
+{
+ ResizeAccuracyTest(cmpF, type, interp, sz, cv::Size{0, 0}, fx, fy, getCompileArgs());
+}
+
+TEST_P(ResizePTest, AccuracyTest)
+{
+ constexpr int planeNum = 3;
+ cv::Size sz_in_p {sz.width, sz.height*planeNum};
+ cv::Size sz_out_p{sz_out.width, sz_out.height*planeNum};
+
+ cv::Mat in_mat(sz_in_p, CV_8UC1);
+ cv::randn(in_mat, cv::Scalar::all(127.0f), cv::Scalar::all(40.f));
+
+ cv::Mat out_mat (sz_out_p, CV_8UC1);
+ cv::Mat out_mat_ocv_p(sz_out_p, CV_8UC1);
+
+ cv::GMatP in;
+ auto out = cv::gapi::resizeP(in, sz_out, interp);
+ cv::GComputation c(cv::GIn(in), cv::GOut(out));
+
+ c.compile(cv::descr_of(in_mat).asPlanar(planeNum), getCompileArgs())
+ (cv::gin(in_mat), cv::gout(out_mat));
+
+ for (int i = 0; i < planeNum; i++) {
+ const cv::Mat in_mat_roi = in_mat(cv::Rect(0, i*sz.height, sz.width, sz.height));
+ cv::Mat out_mat_roi = out_mat_ocv_p(cv::Rect(0, i*sz_out.height, sz_out.width, sz_out.height));
+ cv::resize(in_mat_roi, out_mat_roi, sz_out, 0, 0, interp);
+ }
+
+ // Comparison //////////////////////////////////////////////////////////////
+ {
+ EXPECT_TRUE(cmpF(out_mat, out_mat_ocv_p));
+ }
+}
+
} // opencv_test
#endif //OPENCV_GAPI_IMGPROC_TESTS_INL_HPP
Values(CV_8UC1),
Values(CORE_CPU)));
-INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeTest,
- Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128)),
- Values(-1),
- Values(CORE_CPU),
- Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
- Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
- Values(cv::Size(64,64),
- cv::Size(30,30))));
-
-INSTANTIATE_TEST_CASE_P(ResizePTestCPU, ResizePTest,
- Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128)),
- Values(-1),
- Values(CORE_CPU),
- Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
- Values(cv::INTER_LINEAR),
- Values(cv::Size(64,64),
- cv::Size(30,30))));
-
-INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeTestFxFy,
- Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128)),
- Values(-1),
- Values(CORE_CPU),
- Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
- Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
- Values(0.5, 0.1),
- Values(0.5, 0.1)));
-
INSTANTIATE_TEST_CASE_P(Merge3TestCPU, Merge3Test,
Combine(Values(CV_8UC1),
Values(cv::Size(1280, 720),
Values(-1),
Values(CORE_FLUID)));
-INSTANTIATE_TEST_CASE_P(ResizeTestFluid, ResizeTest,
- Combine(Values(CV_8UC3/*CV_8UC1, CV_16UC1, CV_16SC1*/),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128),
- cv::Size(64, 64),
- cv::Size(30, 30)),
- Values(-1),
- Values(CORE_FLUID),
- Values(Tolerance_FloatRel_IntAbs(1e-5, 1).to_compare_obj()),
- Values(/*cv::INTER_NEAREST,*/ cv::INTER_LINEAR/*, cv::INTER_AREA*/),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128),
- cv::Size(64, 64),
- cv::Size(30, 30))));
-
-INSTANTIATE_TEST_CASE_P(ResizeTestFxFyFluid, ResizeTestFxFy,
- Combine(Values(CV_8UC3/*CV_8UC1, CV_16UC1, CV_16SC1*/),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128),
- cv::Size(64, 64),
- cv::Size(30, 30)),
- Values(-1),
- Values(CORE_FLUID),
- Values(Tolerance_FloatRel_IntAbs(1e-5, 1).to_compare_obj()),
- Values(/*cv::INTER_NEAREST,*/ cv::INTER_LINEAR/*, cv::INTER_AREA*/),
- Values(0.5, 1, 2),
- Values(0.5, 1, 2)));
-
INSTANTIATE_TEST_CASE_P(BackendOutputAllocationTestFluid, BackendOutputAllocationTest,
Combine(Values(CV_8UC3, CV_16SC2, CV_32FC1),
Values(cv::Size(50, 50)),
namespace opencv_test
{
+INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeTest,
+ Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128)),
+ Values(-1),
+ Values(IMGPROC_CPU),
+ Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
+ Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
+ Values(cv::Size(64,64),
+ cv::Size(30,30))));
+
+INSTANTIATE_TEST_CASE_P(ResizePTestCPU, ResizePTest,
+ Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128)),
+ Values(-1),
+ Values(IMGPROC_CPU),
+ Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
+ Values(cv::INTER_LINEAR),
+ Values(cv::Size(64,64),
+ cv::Size(30,30))));
+
+INSTANTIATE_TEST_CASE_P(ResizeTestCPU, ResizeTestFxFy,
+ Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128)),
+ Values(-1),
+ Values(IMGPROC_CPU),
+ Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
+ Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
+ Values(0.5, 0.1),
+ Values(0.5, 0.1)));
+
INSTANTIATE_TEST_CASE_P(Filter2DTestCPU, Filter2DTest,
Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
Values(cv::Size(1280, 720),
namespace opencv_test
{
+INSTANTIATE_TEST_CASE_P(ResizeTestFluid, ResizeTest,
+ Combine(Values(CV_8UC3/*CV_8UC1, CV_16UC1, CV_16SC1*/),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128),
+ cv::Size(64, 64),
+ cv::Size(30, 30)),
+ Values(-1),
+ Values(IMGPROC_FLUID),
+ Values(Tolerance_FloatRel_IntAbs(1e-5, 1).to_compare_obj()),
+ Values(/*cv::INTER_NEAREST,*/ cv::INTER_LINEAR/*, cv::INTER_AREA*/),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128),
+ cv::Size(64, 64),
+ cv::Size(30, 30))));
+
+INSTANTIATE_TEST_CASE_P(ResizeTestFxFyFluid, ResizeTestFxFy,
+ Combine(Values(CV_8UC3/*CV_8UC1, CV_16UC1, CV_16SC1*/),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128),
+ cv::Size(64, 64),
+ cv::Size(30, 30)),
+ Values(-1),
+ Values(IMGPROC_FLUID),
+ Values(Tolerance_FloatRel_IntAbs(1e-5, 1).to_compare_obj()),
+ Values(/*cv::INTER_NEAREST,*/ cv::INTER_LINEAR/*, cv::INTER_AREA*/),
+ Values(0.5, 1, 2),
+ Values(0.5, 1, 2)));
+
INSTANTIATE_TEST_CASE_P(RGB2GrayTestFluid, RGB2GrayTest,
Combine(Values(CV_8UC3),
Values(cv::Size(1280, 720),
}
};
-GAPI_FLUID_KERNEL(FResizeNN1Lpi, cv::gapi::core::GResize, false)
+GAPI_FLUID_KERNEL(FResizeNN1Lpi, cv::gapi::imgproc::GResize, false)
{
static const int Window = 1;
static const auto Kind = GFluidKernel::Kind::Resize;
} // namespace areaUpscale
} // anonymous namespace
-GAPI_FLUID_KERNEL(FResizeLinear1Lpi, cv::gapi::core::GResize, true)
+GAPI_FLUID_KERNEL(FResizeLinear1Lpi, cv::gapi::imgproc::GResize, true)
{
static const int Window = 1;
static const auto Kind = GFluidKernel::Kind::Resize;
};
} // namespace
-GAPI_FLUID_KERNEL(FResizeArea1Lpi, cv::gapi::core::GResize, false)
+GAPI_FLUID_KERNEL(FResizeArea1Lpi, cv::gapi::imgproc::GResize, false)
{
static const int Window = 1;
static const auto Kind = GFluidKernel::Kind::Resize;
}
};
-GAPI_FLUID_KERNEL(FResizeAreaUpscale1Lpi, cv::gapi::core::GResize, true)
+GAPI_FLUID_KERNEL(FResizeAreaUpscale1Lpi, cv::gapi::imgproc::GResize, true)
{
static const int Window = 1;
static const auto Kind = GFluidKernel::Kind::Resize;
#define ADD_RESIZE_KERNEL_WITH_LPI(interp, lpi, scratch) \
struct Resize##interp##lpi##LpiHelper : public FResize##interp##1Lpi { static const int LPI = lpi; }; \
-struct FResize##interp##lpi##Lpi : public cv::GFluidKernelImpl<Resize##interp##lpi##LpiHelper, cv::gapi::core::GResize, scratch>{};
+struct FResize##interp##lpi##Lpi : public cv::GFluidKernelImpl<Resize##interp##lpi##LpiHelper, cv::gapi::imgproc::GResize, scratch>{};
ADD_RESIZE_KERNEL_WITH_LPI(NN, 2, false)
ADD_RESIZE_KERNEL_WITH_LPI(NN, 3, false)
auto out = cv::gapi::resize(rgb, out_sz, 0, 0, interp);
cv::GComputation c(cv::GIn(y, uv), cv::GOut(out));
- auto pkg = cv::gapi::combine(fluidTestPackage, cv::gapi::core::fluid::kernels());
+ auto pkg = cv::gapi::combine(fluidTestPackage, cv::gapi::imgproc::fluid::kernels());
c.apply(cv::gin(y_mat, uv_mat), cv::gout(out_mat)
,cv::compile_args(pkg, cv::GFluidOutputRois{{roi}}));
TEST(Fluid, UnusedNodeOutputReshapeTest)
{
const auto test_size = cv::Size(8, 8);
- const auto get_compile_args =
- [] () { return cv::compile_args(cv::gapi::core::fluid::kernels()); };
+
+ const auto get_compile_args = [] () {
+ return cv::compile_args(
+ cv::gapi::combine(
+ cv::gapi::core::fluid::kernels(),
+ cv::gapi::imgproc::fluid::kernels()
+ )
+ );
+ };
cv::GMat in;
cv::GMat a, b, c, d;
Values(CV_8UC1),
Values(CORE_GPU)));
-INSTANTIATE_TEST_CASE_P(ResizeTestGPU, ResizeTest,
- Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128)),
- Values(-1),
- Values(CORE_GPU),
- Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
- Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
- Values(cv::Size(64,64),
- cv::Size(30,30))));
-
-INSTANTIATE_TEST_CASE_P(ResizeTestGPU, ResizeTestFxFy,
- Combine(Values( CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1 ),
- Values(cv::Size(1280, 720),
- cv::Size(640, 480),
- cv::Size(128, 128)),
- Values(-1),
- Values(CORE_GPU),
- Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
- Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
- Values(0.5, 0.1),
- Values(0.5, 0.1)));
-
INSTANTIATE_TEST_CASE_P(Merge3TestGPU, Merge3Test,
Combine(Values(CV_8UC1),
Values(cv::Size(1280, 720),
namespace opencv_test
{
+INSTANTIATE_TEST_CASE_P(ResizeTestGPU, ResizeTest,
+ Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128)),
+ Values(-1),
+ Values(IMGPROC_GPU),
+ Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
+ Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
+ Values(cv::Size(64,64),
+ cv::Size(30,30))));
+
+INSTANTIATE_TEST_CASE_P(ResizeTestGPU, ResizeTestFxFy,
+ Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
+ Values(cv::Size(1280, 720),
+ cv::Size(640, 480),
+ cv::Size(128, 128)),
+ Values(-1),
+ Values(IMGPROC_GPU),
+ Values(AbsSimilarPoints(2, 0.05).to_compare_obj()),
+ Values(cv::INTER_NEAREST, cv::INTER_LINEAR, cv::INTER_AREA),
+ Values(0.5, 0.1),
+ Values(0.5, 0.1)));
+
INSTANTIATE_TEST_CASE_P(Filter2DTestGPU, Filter2DTest,
Combine(Values(CV_8UC1, CV_8UC3, CV_16UC1, CV_16SC1, CV_32FC1),
Values(cv::Size(1280, 720),
r_nh, op1_nh, op2_nh}),
nodes);
- EXPECT_EQ(cv::gapi::core::GResize::id(), matching_test::opName(tgm, op1_nh));
+ EXPECT_EQ(cv::gapi::imgproc::GResize::id(), matching_test::opName(tgm, op1_nh));
EXPECT_EQ(cv::gapi::core::GSplit3::id(), matching_test::opName(tgm, op2_nh));
EXPECT_EQ(1u, tmp_nh->outEdges().size());
EXPECT_EQ(matching_test::S({bgr_nh, tmp_nh, plr_nh, op1_nh, op2_nh}),
nodes);
- EXPECT_EQ(cv::gapi::core::GResize::id(), matching_test::opName(tgm, op1_nh));
+ EXPECT_EQ(cv::gapi::imgproc::GResize::id(), matching_test::opName(tgm, op1_nh));
EXPECT_EQ(GToNCHW::id(), matching_test::opName(tgm, op2_nh));
EXPECT_EQ(1u, tmp_nh->outEdges().size());
};
G_TYPED_KERNEL(MyPlanarResize, <GMatP(GMatP, Size, int)>, "test.my_planar_resize") {
static GMatDesc outMeta(GMatDesc in, Size sz, int interp) {
- return cv::gapi::core::GResizeP::outMeta(in, sz, interp);
+ return cv::gapi::imgproc::GResizeP::outMeta(in, sz, interp);
}
};
GAPI_OCV_KERNEL(MyPlanarResizeImpl, MyPlanarResize) {
};
G_TYPED_KERNEL(MyInterleavedResize, <GMat(GMat, Size, int)>, "test.my_interleaved_resize") {
static GMatDesc outMeta(GMatDesc in, Size sz, int interp) {
- return cv::gapi::core::GResize::outMeta(in, sz, 0.0, 0.0, interp);
+ return cv::gapi::imgproc::GResize::outMeta(in, sz, 0.0, 0.0, interp);
}
};
GAPI_OCV_KERNEL(MyInterleavedResizeImpl, MyInterleavedResize) {
cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
cv::Mat out_mat1, out_mat2;
- cc.apply(in_mat1, out_mat1, cv::compile_args(cv::gapi::core::fluid::kernels()));
+ cc.apply(in_mat1, out_mat1, cv::compile_args(cv::gapi::imgproc::fluid::kernels()));
auto comp1 = cc.priv().m_lastCompiled;
cc.apply(in_mat2, out_mat2);
cv::randu(in_mat3, cv::Scalar::all(0), cv::Scalar::all(255));
cv::Mat out_mat1, out_mat2, out_mat3;
- cc.apply(in_mat1, out_mat1, cv::compile_args(cv::gapi::core::fluid::kernels()));
+ cc.apply(in_mat1, out_mat1, cv::compile_args(cv::gapi::imgproc::fluid::kernels()));
auto comp1 = cc.priv().m_lastCompiled;
cc.apply(in_mat2, out_mat2);
#include <opencv2/gapi.hpp>
-#include <opencv2/gapi/core.hpp>
-#include <opencv2/gapi/cpu/core.hpp>
+#include <opencv2/gapi/cpu/imgproc.hpp>
+#include <opencv2/gapi/imgproc.hpp>
int main(int argc, char *argv[])
{
out_vector += cv::gout(out_mat2);
// ! [GRunArgsP usage]
- auto stream = cc.compileStreaming(cv::compile_args(cv::gapi::core::cpu::kernels()));
+ auto stream = cc.compileStreaming(cv::compile_args(cv::gapi::imgproc::cpu::kernels()));
stream.setSource(std::move(in_vector));
stream.start();