mirror of
https://github.com/opencv/opencv.git
synced 2024-11-29 22:00:25 +08:00
Added OpenVX based processing to boxFilter
This commit is contained in:
parent
179a6e0cca
commit
6d55e99291
@ -44,6 +44,11 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
#define IVX_HIDE_INFO_WARNINGS
|
||||
#define IVX_USE_OPENCV
|
||||
#include "ivx.hpp"
|
||||
#endif
|
||||
/*
|
||||
* This file includes the code, contributed by Simon Perreault
|
||||
* (the function icvMedianBlur_8u_O1)
|
||||
@ -1634,6 +1639,111 @@ cv::Ptr<cv::FilterEngine> cv::createBoxFilter( int srcType, int dstType, Size ks
|
||||
srcType, dstType, sumType, borderType );
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace cv
|
||||
{
|
||||
static bool openvx_boxfilter(InputArray _src, OutputArray _dst, int ddepth,
|
||||
Size ksize, Point anchor,
|
||||
bool normalize, int borderType)
|
||||
{
|
||||
int stype = _src.type();
|
||||
if (ddepth < 0)
|
||||
ddepth = CV_8UC1;
|
||||
if (stype != CV_8UC1 || (ddepth != CV_8U && ddepth != CV_16S) ||
|
||||
(anchor.x >= 0 && anchor.x != ksize.width / 2) ||
|
||||
(anchor.y >= 0 && anchor.y != ksize.height / 2) ||
|
||||
ksize.width % 2 != 1 || ksize.height % 2 != 1 ||
|
||||
ksize.width < 3 || ksize.height < 3)
|
||||
return false;
|
||||
|
||||
Mat src = _src.getMat();
|
||||
_dst.create(src.size(), CV_MAKETYPE(ddepth, 1));
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
if (src.cols < ksize.width || src.rows < ksize.height)
|
||||
return false;
|
||||
|
||||
if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix())
|
||||
return false; //Process isolated borders only
|
||||
vx_border_t border;
|
||||
switch (borderType & ~BORDER_ISOLATED)
|
||||
{
|
||||
case BORDER_CONSTANT:
|
||||
border.mode = VX_BORDER_CONSTANT;
|
||||
#if VX_VERSION > VX_VERSION_1_0
|
||||
border.constant_value.U8 = (vx_uint8)(0);
|
||||
#else
|
||||
border.constant_value = (vx_uint32)(0);
|
||||
#endif
|
||||
break;
|
||||
case BORDER_REPLICATE:
|
||||
border.mode = VX_BORDER_REPLICATE;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ivx::Context::create();
|
||||
if ((vx_size)(ksize.width) > ctx.convolutionMaxDimension() || (vx_size)(ksize.height) > ctx.convolutionMaxDimension())
|
||||
return false;
|
||||
|
||||
Mat a;
|
||||
if (dst.data != src.data)
|
||||
a = src;
|
||||
else
|
||||
src.copyTo(a);
|
||||
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data),
|
||||
ib = ivx::Image::createFromHandle(ctx, ddepth == CV_16S ? VX_DF_IMAGE_S16 : VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(dst.cols, dst.rows, ddepth == CV_16S ? 2 : 1, (vx_int32)(dst.step)), dst.data);
|
||||
|
||||
//ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments
|
||||
//since OpenVX standart says nothing about thread-safety for now
|
||||
vx_border_t prevBorder = ctx.borderMode();
|
||||
ctx.setBorderMode(border);
|
||||
if (ddepth == CV_8U && ksize.width == 3 && ksize.height == 3 && normalize)
|
||||
{
|
||||
ivx::IVX_CHECK_STATUS(vxuBox3x3(ctx, ia, ib));
|
||||
}
|
||||
else
|
||||
{
|
||||
#if VX_VERSION <= VX_VERSION_1_0
|
||||
if (ctx.vendorID() == VX_ID_KHRONOS && ((vx_size)(src.cols) <= ctx.convolutionMaxDimension() || (vx_size)(src.rows) <= ctx.convolutionMaxDimension()))
|
||||
{
|
||||
ctx.setBorderMode(prevBorder);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
Mat convData(ksize, CV_16SC1);
|
||||
convData = normalize ? (1 << 15) / (ksize.width * ksize.height) : 1;
|
||||
ivx::Convolution cnv = ivx::Convolution::create(ctx, convData.cols, convData.rows);
|
||||
cnv.copyFrom(convData);
|
||||
if (normalize)
|
||||
cnv.setScale(1 << 15);
|
||||
ivx::IVX_CHECK_STATUS(vxuConvolve(ctx, ia, cnv, ib));
|
||||
}
|
||||
ctx.setBorderMode(prevBorder);
|
||||
}
|
||||
catch (ivx::RuntimeError & e)
|
||||
{
|
||||
CV_Error(CV_StsInternal, e.what());
|
||||
return false;
|
||||
}
|
||||
catch (ivx::WrapperError & e)
|
||||
{
|
||||
CV_Error(CV_StsInternal, e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: IPP performance regression
|
||||
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK
|
||||
namespace cv
|
||||
@ -1745,6 +1855,11 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
|
||||
|
||||
CV_OCL_RUN(_dst.isUMat(), ocl_boxFilter(_src, _dst, ddepth, ksize, anchor, borderType, normalize))
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
if (openvx_boxfilter(_src, _dst, ddepth, ksize, anchor, normalize, borderType))
|
||||
return;
|
||||
#endif
|
||||
|
||||
Mat src = _src.getMat();
|
||||
int stype = src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
|
||||
if( ddepth < 0 )
|
||||
|
Loading…
Reference in New Issue
Block a user