Commit b46364e4 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #7996 from mshabunin:hal-filter-revert

parents e0ee2f76 c4c1c4c9
...@@ -10,52 +10,92 @@ namespace cv { namespace hal { ...@@ -10,52 +10,92 @@ namespace cv { namespace hal {
//! @addtogroup imgproc_hal_functions //! @addtogroup imgproc_hal_functions
//! @{ //! @{
//---------------------------
//! @cond IGNORED
struct CV_EXPORTS Filter2D struct CV_EXPORTS Filter2D
{ {
static Ptr<hal::Filter2D> create(uchar * kernel_data, size_t kernel_step, int kernel_type, CV_DEPRECATED static Ptr<hal::Filter2D> create(uchar * , size_t , int ,
int kernel_width, int kernel_height, int , int ,
int max_width, int max_height, int , int ,
int stype, int dtype, int , int ,
int borderType, double delta, int , double ,
int anchor_x, int anchor_y, int , int ,
bool isSubmatrix, bool isInplace); bool , bool );
virtual void apply(uchar * src_data, size_t src_step, virtual void apply(uchar * , size_t ,
uchar * dst_data, size_t dst_step, uchar * , size_t ,
int width, int height, int , int ,
int full_width, int full_height, int , int ,
int offset_x, int offset_y) = 0; int , int ) = 0;
virtual ~Filter2D() {} virtual ~Filter2D() {}
}; };
struct CV_EXPORTS SepFilter2D struct CV_EXPORTS SepFilter2D
{ {
static Ptr<hal::SepFilter2D> create(int stype, int dtype, int ktype, CV_DEPRECATED static Ptr<hal::SepFilter2D> create(int , int , int ,
uchar * kernelx_data, int kernelx_len, uchar * , int ,
uchar * kernely_data, int kernely_len, uchar * , int ,
int anchor_x, int anchor_y, int , int ,
double delta, int borderType); double , int );
virtual void apply(uchar * src_data, size_t src_step, virtual void apply(uchar * , size_t ,
uchar * dst_data, size_t dst_step, uchar * , size_t ,
int width, int height, int , int ,
int full_width, int full_height, int , int ,
int offset_x, int offset_y) = 0; int , int ) = 0;
virtual ~SepFilter2D() {} virtual ~SepFilter2D() {}
}; };
struct CV_EXPORTS Morph struct CV_EXPORTS Morph
{ {
static Ptr<Morph> create(int op, int src_type, int dst_type, int max_width, int max_height, CV_DEPRECATED static Ptr<hal::Morph> create(int , int , int , int , int ,
int kernel_type, uchar * kernel_data, size_t kernel_step, int , uchar * , size_t ,
int , int ,
int , int ,
int , const double *,
int , bool , bool );
virtual void apply(uchar * , size_t , uchar * , size_t , int , int ,
int , int , int , int ,
int , int , int , int ) = 0;
virtual ~Morph() {}
};
//! @endcond
//---------------------------
CV_EXPORTS void filter2D(int stype, int dtype, int kernel_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y,
uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height, int kernel_width, int kernel_height,
int anchor_x, int anchor_y, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], double delta, int borderType,
int iterations, bool isSubmatrix, bool allowInplace); bool isSubmatrix);
virtual void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
CV_EXPORTS void sepFilter2D(int stype, int dtype, int ktype,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y,
uchar * kernelx_data, int kernelx_len,
uchar * kernely_data, int kernely_len,
int anchor_x, int anchor_y,
double delta, int borderType);
CV_EXPORTS void morph(int op, int src_type, int dst_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y, int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2) = 0; int roi_width2, int roi_height2, int roi_x2, int roi_y2,
virtual ~Morph() {} int kernel_type, uchar * kernel_data, size_t kernel_step,
}; int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4],
int iterations, bool isSubmatrix);
CV_EXPORTS void resize(int src_type, CV_EXPORTS void resize(int src_type,
......
...@@ -4509,39 +4509,29 @@ cv::Ptr<cv::FilterEngine> cv::createLinearFilter( int _srcType, int _dstType, ...@@ -4509,39 +4509,29 @@ cv::Ptr<cv::FilterEngine> cv::createLinearFilter( int _srcType, int _dstType,
using namespace cv; using namespace cv;
struct ReplacementFilter : public hal::Filter2D static bool replacementFilter2D(int stype, int dtype, int kernel_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y,
uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
double delta, int borderType, bool isSubmatrix)
{ {
cvhalFilter2D* ctx; cvhalFilter2D* ctx;
bool isInitialized; int res = cv_hal_filterInit(&ctx, kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, width, height,
ReplacementFilter() : ctx(0), isInitialized(false) { } stype, dtype, borderType, delta, anchor_x, anchor_y, isSubmatrix, src_data == dst_data);
bool init(uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width,
int kernel_height, int max_width, int max_height, int stype, int dtype, int borderType, double delta,
int anchor_x, int anchor_y, bool isSubmatrix, bool isInplace)
{
int res = cv_hal_filterInit(&ctx, kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, max_width, max_height,
stype, dtype, borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace);
isInitialized = (res == CV_HAL_ERROR_OK);
return isInitialized;
}
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
{
if (isInitialized)
{
int res = cv_hal_filter(ctx, src_data, src_step, dst_data, dst_step, width, height, full_width, full_height, offset_x, offset_y);
if (res != CV_HAL_ERROR_OK) if (res != CV_HAL_ERROR_OK)
CV_Error(Error::StsNotImplemented, "HAL Filter returned an error"); return false;
} res = cv_hal_filter(ctx, src_data, src_step, dst_data, dst_step, width, height, full_width, full_height, offset_x, offset_y);
} bool success = (res == CV_HAL_ERROR_OK);
~ReplacementFilter() res = cv_hal_filterFree(ctx);
{
if (isInitialized)
{
int res = cv_hal_filterFree(ctx);
if (res != CV_HAL_ERROR_OK) if (res != CV_HAL_ERROR_OK)
CV_Error(Error::StsNotImplemented, "HAL Filter Free returned an error"); return false;
} return success;
} }
};
#ifdef HAVE_IPP #ifdef HAVE_IPP
typedef IppStatus(CV_STDCALL* IppiFilterBorder)( typedef IppStatus(CV_STDCALL* IppiFilterBorder)(
...@@ -4613,8 +4603,17 @@ struct IppFilterTrait<CV_32F> ...@@ -4613,8 +4603,17 @@ struct IppFilterTrait<CV_32F>
}; };
template <int kdepth> template <int kdepth>
struct IppFilter : public hal::Filter2D static bool ippFilter2D(int stype, int dtype,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
double delta, int borderType, bool isSubmatrix)
{ {
CV_INSTRUMENT_REGION_IPP();
typedef IppFilterTrait<kdepth> trait; typedef IppFilterTrait<kdepth> trait;
typedef typename trait::kernel_type kernel_type; typedef typename trait::kernel_type kernel_type;
...@@ -4624,10 +4623,6 @@ struct IppFilter : public hal::Filter2D ...@@ -4624,10 +4623,6 @@ struct IppFilter : public hal::Filter2D
IppiBorderType ippBorderType; IppiBorderType ippBorderType;
int src_type; int src_type;
bool init(uchar* kernel_data, size_t kernel_step, int, int kernel_width, int kernel_height,
int max_width, int max_height, int stype, int dtype,
int borderType, double delta, int anchor_x, int anchor_y, bool isSubmatrix, bool isInplace)
{
Point anchor(anchor_x, anchor_y); Point anchor(anchor_x, anchor_y);
#if IPP_VERSION_X100 >= 900 #if IPP_VERSION_X100 >= 900
Point ippAnchor((kernel_width - 1) / 2, (kernel_height - 1) / 2); Point ippAnchor((kernel_width - 1) / 2, (kernel_height - 1) / 2);
...@@ -4653,7 +4648,7 @@ struct IppFilter : public hal::Filter2D ...@@ -4653,7 +4648,7 @@ struct IppFilter : public hal::Filter2D
&& (!isSubmatrix || isIsolated) && (!isSubmatrix || isIsolated)
&& (std::fabs(delta - 0) < DBL_EPSILON) && (std::fabs(delta - 0) < DBL_EPSILON)
&& (ippAnchor == anchor) && (ippAnchor == anchor)
&& !isInplace; && src_data != dst_data;
if (!runIpp) if (!runIpp)
return false; return false;
...@@ -4665,10 +4660,12 @@ struct IppFilter : public hal::Filter2D ...@@ -4665,10 +4660,12 @@ struct IppFilter : public hal::Filter2D
IppDataType kernelType = ippiGetDataType(kdepth); IppDataType kernelType = ippiGetDataType(kdepth);
Ipp32s specSize = 0; Ipp32s specSize = 0;
Ipp32s bufsize = 0; Ipp32s bufsize = 0;
IppiSize dstRoiSize = { max_width, max_height }; IppiSize dstRoiSize = { width, height };
IppStatus status; IppStatus status;
status = ippiFilterBorderGetSize(kernelSize, dstRoiSize, dataType, kernelType, cn, &specSize, &bufsize); status = ippiFilterBorderGetSize(kernelSize, dstRoiSize, dataType, kernelType, cn, &specSize, &bufsize);
if (status >= 0) { if (status < 0)
return false;
kernel_type* pKerBuffer = (kernel_type*)kernel_data; kernel_type* pKerBuffer = (kernel_type*)kernel_data;
size_t good_kernel_step = sizeof(kernel_type) * static_cast<size_t>(kernelSize.width); size_t good_kernel_step = sizeof(kernel_type) * static_cast<size_t>(kernelSize.width);
#if IPP_VERSION_X100 >= 900 #if IPP_VERSION_X100 >= 900
...@@ -4689,40 +4686,29 @@ struct IppFilter : public hal::Filter2D ...@@ -4689,40 +4686,29 @@ struct IppFilter : public hal::Filter2D
spec.Alloc(specSize); spec.Alloc(specSize);
buffer.Alloc(bufsize); buffer.Alloc(bufsize);
status = trait::runInit(pKerBuffer, kernelSize, 0, dataType, cn, ippRndFinancial, spec); status = trait::runInit(pKerBuffer, kernelSize, 0, dataType, cn, ippRndFinancial, spec);
if (status >= 0) { if (status < 0) {
return true;
}
}
return false; return false;
} }
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int, int, int, int)
{
CV_INSTRUMENT_REGION_IPP()
if (dst_data == src_data)
CV_Error(Error::StsBadArg, "Inplace IPP Filter2D is not supported");
IppiFilterBorder ippiFilterBorder = getIppFunc(src_type); IppiFilterBorder ippiFilterBorder = getIppFunc(src_type);
IppiSize dstRoiSize = { width, height };
kernel_type borderValue[4] = { 0, 0, 0, 0 }; kernel_type borderValue[4] = { 0, 0, 0, 0 };
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiFilterBorder, src_data, (int)src_step, dst_data, (int)dst_step, dstRoiSize, ippBorderType, borderValue, spec, buffer); status = CV_INSTRUMENT_FUN_IPP(ippiFilterBorder, src_data, (int)src_step, dst_data, (int)dst_step, dstRoiSize, ippBorderType, borderValue, spec, buffer);
if (status >= 0) { if (status >= 0) {
CV_IMPL_ADD(CV_IMPL_IPP); CV_IMPL_ADD(CV_IMPL_IPP);
return true;
} }
} return false;
}; }
#endif #endif
struct DftFilter : public hal::Filter2D static bool dftFilter2D(int stype, int dtype, int kernel_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
double delta, int borderType)
{ {
int src_type;
int dst_type;
double delta;
Mat kernel;
Point anchor;
int borderType;
static bool isAppropriate(int stype, int dtype, int kernel_width, int kernel_height)
{ {
#if CV_SSE2 #if CV_SSE2
int sdepth = CV_MAT_DEPTH(stype); int sdepth = CV_MAT_DEPTH(stype);
...@@ -4733,32 +4719,19 @@ struct DftFilter : public hal::Filter2D ...@@ -4733,32 +4719,19 @@ struct DftFilter : public hal::Filter2D
CV_UNUSED(dtype); CV_UNUSED(dtype);
int dft_filter_size = 50; int dft_filter_size = 50;
#endif #endif
return kernel_width * kernel_height >= dft_filter_size; if (kernel_width * kernel_height < dft_filter_size)
}
bool init(uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
int, int, int stype, int dtype,
int borderType_, double delta_, int anchor_x, int anchor_y, bool, bool)
{
anchor = Point(anchor_x, anchor_y);
borderType = borderType_;
kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
src_type = stype;
dst_type = dtype;
delta = delta_;
if (isAppropriate(stype, dtype, kernel_width, kernel_height))
return true;
return false; return false;
} }
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int, int, int, int) Point anchor = Point(anchor_x, anchor_y);
{ Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
Mat src(Size(width, height), src_type, src_data, src_step);
Mat dst(Size(width, height), dst_type, dst_data, dst_step); Mat src(Size(width, height), stype, src_data, src_step);
Mat dst(Size(width, height), dtype, dst_data, dst_step);
Mat temp; Mat temp;
int src_channels = CV_MAT_CN(src_type); int src_channels = CV_MAT_CN(stype);
int dst_channels = CV_MAT_CN(dst_type); int dst_channels = CV_MAT_CN(dtype);
int ddepth = CV_MAT_DEPTH(dst_type); int ddepth = CV_MAT_DEPTH(dtype);
// crossCorr doesn't accept non-zero delta with multiple channels // crossCorr doesn't accept non-zero delta with multiple channels
if (src_channels != 1 && delta != 0) { if (src_channels != 1 && delta != 0) {
// The semantics of filter2D require that the delta be applied // The semantics of filter2D require that the delta be applied
...@@ -4767,7 +4740,7 @@ struct DftFilter : public hal::Filter2D ...@@ -4767,7 +4740,7 @@ struct DftFilter : public hal::Filter2D
// we just use that. // we just use that.
int corrDepth = ddepth; int corrDepth = ddepth;
if ((ddepth == CV_32F || ddepth == CV_64F) && src_data != dst_data) { if ((ddepth == CV_32F || ddepth == CV_64F) && src_data != dst_data) {
temp = Mat(Size(width, height), dst_type, dst_data, dst_step); temp = Mat(Size(width, height), dtype, dst_data, dst_step);
} else { } else {
corrDepth = ddepth == CV_64F ? CV_64F : CV_32F; corrDepth = ddepth == CV_64F ? CV_64F : CV_32F;
temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels)); temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels));
...@@ -4781,114 +4754,77 @@ struct DftFilter : public hal::Filter2D ...@@ -4781,114 +4754,77 @@ struct DftFilter : public hal::Filter2D
} }
} else { } else {
if (src_data != dst_data) if (src_data != dst_data)
temp = Mat(Size(width, height), dst_type, dst_data, dst_step); temp = Mat(Size(width, height), dtype, dst_data, dst_step);
else else
temp.create(Size(width, height), dst_type); temp.create(Size(width, height), dtype);
crossCorr(src, kernel, temp, src.size(), crossCorr(src, kernel, temp, src.size(),
CV_MAKETYPE(ddepth, src_channels), CV_MAKETYPE(ddepth, src_channels),
anchor, delta, borderType); anchor, delta, borderType);
if (temp.data != dst_data) if (temp.data != dst_data)
temp.copyTo(dst); temp.copyTo(dst);
} }
} return true;
}; }
struct OcvFilter : public hal::Filter2D static void ocvFilter2D(int stype, int dtype, int kernel_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y,
uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
double delta, int borderType)
{ {
Ptr<FilterEngine> f;
int src_type;
int dst_type;
bool isIsolated;
bool init(uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width,
int kernel_height, int, int, int stype, int dtype, int borderType, double delta,
int anchor_x, int anchor_y, bool, bool)
{
isIsolated = (borderType & BORDER_ISOLATED) != 0;
src_type = stype;
dst_type = dtype;
int borderTypeValue = borderType & ~BORDER_ISOLATED; int borderTypeValue = borderType & ~BORDER_ISOLATED;
Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step); Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
f = createLinearFilter(src_type, dst_type, kernel, Point(anchor_x, anchor_y), delta, Ptr<FilterEngine> f = createLinearFilter(stype, dtype, kernel, Point(anchor_x, anchor_y), delta,
borderTypeValue); borderTypeValue);
return true; Mat src(Size(width, height), stype, src_data, src_step);
} Mat dst(Size(width, height), dtype, dst_data, dst_step);
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y)
{
Mat src(Size(width, height), src_type, src_data, src_step);
Mat dst(Size(width, height), dst_type, dst_data, dst_step);
f->apply(src, dst, Size(full_width, full_height), Point(offset_x, offset_y)); f->apply(src, dst, Size(full_width, full_height), Point(offset_x, offset_y));
} }
};
struct ReplacementSepFilter : public hal::SepFilter2D static bool replacementSepFilter(int stype, int dtype, int ktype,
{ uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
cvhalFilter2D *ctx; int width, int height, int full_width, int full_height,
bool isInitialized; int offset_x, int offset_y,
ReplacementSepFilter() : ctx(0), isInitialized(false) {}
bool init(int stype, int dtype, int ktype,
uchar * kernelx_data, int kernelx_len, uchar * kernelx_data, int kernelx_len,
uchar * kernely_data, int kernely_len, uchar * kernely_data, int kernely_len,
int anchor_x, int anchor_y, double delta, int borderType) int anchor_x, int anchor_y, double delta, int borderType)
{ {
cvhalFilter2D *ctx;
int res = cv_hal_sepFilterInit(&ctx, stype, dtype, ktype, int res = cv_hal_sepFilterInit(&ctx, stype, dtype, ktype,
kernelx_data, kernelx_len, kernelx_data, kernelx_len,
kernely_data, kernely_len, kernely_data, kernely_len,
anchor_x, anchor_y, delta, borderType); anchor_x, anchor_y, delta, borderType);
isInitialized = (res == CV_HAL_ERROR_OK);
return isInitialized;
}
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int full_width, int full_height,
int offset_x, int offset_y)
{
if (isInitialized)
{
int res = cv_hal_sepFilter(ctx, src_data, src_step, dst_data, dst_step, width, height, full_width, full_height, offset_x, offset_y);
if (res != CV_HAL_ERROR_OK) if (res != CV_HAL_ERROR_OK)
CV_Error(Error::StsNotImplemented, "Failed to run HAL sepFilter implementation"); return false;
} res = cv_hal_sepFilter(ctx, src_data, src_step, dst_data, dst_step, width, height, full_width, full_height, offset_x, offset_y);
} bool success = (res == CV_HAL_ERROR_OK);
~ReplacementSepFilter() res = cv_hal_sepFilterFree(ctx);
{
if (isInitialized)
{
int res = cv_hal_sepFilterFree(ctx);
if (res != CV_HAL_ERROR_OK) if (res != CV_HAL_ERROR_OK)
CV_Error(Error::StsNotImplemented, "Failed to run HAL sepFilter implementation"); return false;
} return success;
} }
};
struct OcvSepFilter : public hal::SepFilter2D static void ocvSepFilter(int stype, int dtype, int ktype,
{ uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
Ptr<FilterEngine> f; int width, int height, int full_width, int full_height,
int src_type; int offset_x, int offset_y,
int dst_type;
bool init(int stype, int dtype, int ktype,
uchar * kernelx_data, int kernelx_len, uchar * kernelx_data, int kernelx_len,
uchar * kernely_data, int kernely_len, uchar * kernely_data, int kernely_len,
int anchor_x, int anchor_y, double delta, int borderType) int anchor_x, int anchor_y, double delta, int borderType)
{ {
src_type = stype;
dst_type = dtype;
Mat kernelX(Size(kernelx_len, 1), ktype, kernelx_data); Mat kernelX(Size(kernelx_len, 1), ktype, kernelx_data);
Mat kernelY(Size(kernely_len, 1), ktype, kernely_data); Mat kernelY(Size(kernely_len, 1), ktype, kernely_data);
Ptr<FilterEngine> f = createSeparableLinearFilter(stype, dtype, kernelX, kernelY,
f = createSeparableLinearFilter( stype, dtype, kernelX, kernelY,
Point(anchor_x, anchor_y), Point(anchor_x, anchor_y),
delta, borderType & ~BORDER_ISOLATED ); delta, borderType & ~BORDER_ISOLATED);
return true; Mat src(Size(width, height), stype, src_data, src_step);
} Mat dst(Size(width, height), dtype, dst_data, dst_step);
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int full_width, int full_height,
int offset_x, int offset_y)
{
Mat src(Size(width, height), src_type, src_data, src_step);
Mat dst(Size(width, height), dst_type, dst_data, dst_step);
f->apply(src, dst, Size(full_width, full_height), Point(offset_x, offset_y)); f->apply(src, dst, Size(full_width, full_height), Point(offset_x, offset_y));
}
}; };
//=================================================================== //===================================================================
...@@ -4898,97 +4834,124 @@ struct OcvSepFilter : public hal::SepFilter2D ...@@ -4898,97 +4834,124 @@ struct OcvSepFilter : public hal::SepFilter2D
namespace cv { namespace cv {
namespace hal { namespace hal {
Ptr<hal::Filter2D> Filter2D::create(uchar* kernel_data, size_t kernel_step, int kernel_type,
CV_DEPRECATED Ptr<hal::Filter2D> Filter2D::create(uchar * , size_t , int ,
int , int ,
int , int ,
int , int ,
int , double ,
int , int ,
bool , bool ) { return Ptr<hal::Filter2D>(); }
CV_DEPRECATED Ptr<hal::SepFilter2D> SepFilter2D::create(int , int , int ,
uchar * , int ,
uchar * , int ,
int , int ,
double , int ) { return Ptr<hal::SepFilter2D>(); }
void filter2D(int stype, int dtype, int kernel_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int full_width, int full_height,
int offset_x, int offset_y,
uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height, int kernel_width, int kernel_height,
int max_width, int max_height, int anchor_x, int anchor_y,
int stype, int dtype, double delta, int borderType,
int borderType, double delta, int anchor_x, int anchor_y, bool isSubmatrix, bool isInplace) bool isSubmatrix)
{ {
{ bool res;
ReplacementFilter* impl = new ReplacementFilter(); res = replacementFilter2D(stype, dtype, kernel_type,
if (impl->init(kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, src_data, src_step,
max_width, max_height, stype, dtype, dst_data, dst_step,
borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace)) width, height,
{ full_width, full_height,
return Ptr<hal::Filter2D>(impl); offset_x, offset_y,
} kernel_data, kernel_step,
delete impl; kernel_width, kernel_height,
} anchor_x, anchor_y,
delta, borderType, isSubmatrix);
if (res)
return;
#ifdef HAVE_IPP #ifdef HAVE_IPP
CV_IPP_CHECK() CV_IPP_CHECK()
{ {
res = false;
if (kernel_type == CV_32FC1) { if (kernel_type == CV_32FC1) {
IppFilter<CV_32F>* impl = new IppFilter<CV_32F>(); res = ippFilter2D<CV_32F>(stype, dtype,
if (impl->init(kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, src_data, src_step,
max_width, max_height, stype, dtype, dst_data, dst_step,
borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace)) width, height,
{ kernel_data, kernel_step,
return Ptr<hal::Filter2D>(impl); kernel_width, kernel_height,
} anchor_x, anchor_y,
delete impl; delta, borderType, isSubmatrix);
} }
else if (kernel_type == CV_16SC1) {
if (kernel_type == CV_16SC1) { res = ippFilter2D<CV_16S>(stype, dtype,
IppFilter<CV_16S>* impl = new IppFilter<CV_16S>(); src_data, src_step,
if (impl->init(kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, dst_data, dst_step,
max_width, max_height, stype, dtype, width, height,
borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace)) kernel_data, kernel_step,
{ kernel_width, kernel_height,
return Ptr<hal::Filter2D>(impl); anchor_x, anchor_y,
} delta, borderType, isSubmatrix);
delete impl; }
} if (res)
return;
} }
#endif #endif
res = dftFilter2D(stype, dtype, kernel_type,
if (DftFilter::isAppropriate(stype, dtype, kernel_width, kernel_height)) src_data, src_step,
{ dst_data, dst_step,
DftFilter* impl = new DftFilter(); width, height,
if (impl->init(kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, kernel_data, kernel_step,
max_width, max_height, stype, dtype, kernel_width, kernel_height,
borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace)) anchor_x, anchor_y,
{ delta, borderType);
return Ptr<hal::Filter2D>(impl); if (res)
} return;
delete impl; ocvFilter2D(stype, dtype, kernel_type,
} src_data, src_step,
dst_data, dst_step,
{ width, height,
OcvFilter* impl = new OcvFilter(); full_width, full_height,
impl->init(kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, offset_x, offset_y,
max_width, max_height, stype, dtype, kernel_data, kernel_step,
borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace); kernel_width, kernel_height,
return Ptr<hal::Filter2D>(impl); anchor_x, anchor_y,
} delta, borderType);
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
Ptr<SepFilter2D> SepFilter2D::create(int stype, int dtype, int ktype, void sepFilter2D(int stype, int dtype, int ktype,
uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
int width, int height, int full_width, int full_height,
int offset_x, int offset_y,
uchar * kernelx_data, int kernelx_len, uchar * kernelx_data, int kernelx_len,
uchar * kernely_data, int kernely_len, uchar * kernely_data, int kernely_len,
int anchor_x, int anchor_y, double delta, int borderType) int anchor_x, int anchor_y, double delta, int borderType)
{ {
{
ReplacementSepFilter * impl = new ReplacementSepFilter(); bool res = replacementSepFilter(stype, dtype, ktype,
if (impl->init(stype, dtype, ktype, src_data, src_step, dst_data, dst_step,
width, height, full_width, full_height,
offset_x, offset_y,
kernelx_data, kernelx_len, kernelx_data, kernelx_len,
kernely_data, kernely_len, kernely_data, kernely_len,
anchor_x, anchor_y, delta, borderType)) anchor_x, anchor_y, delta, borderType);
{ if (res)
return Ptr<hal::SepFilter2D>(impl); return;
} ocvSepFilter(stype, dtype, ktype,
delete impl; src_data, src_step, dst_data, dst_step,
} width, height, full_width, full_height,
{ offset_x, offset_y,
OcvSepFilter * impl = new OcvSepFilter();
impl->init(stype, dtype, ktype,
kernelx_data, kernelx_len, kernelx_data, kernelx_len,
kernely_data, kernely_len, kernely_data, kernely_len,
anchor_x, anchor_y, delta, borderType); anchor_x, anchor_y, delta, borderType);
return Ptr<hal::SepFilter2D>(impl);
}
} }
} // cv::hal:: } // cv::hal::
...@@ -5021,10 +4984,12 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth, ...@@ -5021,10 +4984,12 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
if( (borderType & BORDER_ISOLATED) == 0 ) if( (borderType & BORDER_ISOLATED) == 0 )
src.locateROI( wsz, ofs ); src.locateROI( wsz, ofs );
Ptr<hal::Filter2D> c = hal::Filter2D::create(kernel.data, kernel.step, kernel.type(), kernel.cols, kernel.rows, hal::filter2D(src.type(), dst.type(), kernel.type(),
dst.cols, dst.rows, src.type(), dst.type(), src.data, src.step, dst.data, dst.step,
borderType, delta, anchor.x, anchor.y, src.isSubmatrix(), src.data == dst.data); dst.cols, dst.rows, wsz.width, wsz.height, ofs.x, ofs.y,
c->apply(src.data, src.step, dst.data, dst.step, dst.cols, dst.rows, wsz.width, wsz.height, ofs.x, ofs.y); kernel.data, kernel.step, kernel.cols, kernel.rows,
anchor.x, anchor.y,
delta, borderType, src.isSubmatrix());
} }
void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth, void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
...@@ -5055,11 +5020,13 @@ void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth, ...@@ -5055,11 +5020,13 @@ void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
Mat contKernelX = kernelX.isContinuous() ? kernelX : kernelX.clone(); Mat contKernelX = kernelX.isContinuous() ? kernelX : kernelX.clone();
Mat contKernelY = kernelY.isContinuous() ? kernelY : kernelY.clone(); Mat contKernelY = kernelY.isContinuous() ? kernelY : kernelY.clone();
Ptr<hal::SepFilter2D> c = hal::SepFilter2D::create(src.type(), dst.type(), kernelX.type(),
hal::sepFilter2D(src.type(), dst.type(), kernelX.type(),
src.data, src.step, dst.data, dst.step,
dst.cols, dst.rows, wsz.width, wsz.height, ofs.x, ofs.y,
contKernelX.data, kernelX.cols + kernelX.rows - 1, contKernelX.data, kernelX.cols + kernelX.rows - 1,
contKernelY.data, kernelY.cols + kernelY.rows - 1, contKernelY.data, kernelY.cols + kernelY.rows - 1,
anchor.x, anchor.y, delta, borderType & ~BORDER_ISOLATED); anchor.x, anchor.y, delta, borderType & ~BORDER_ISOLATED);
c->apply(src.data, src.step, dst.data, dst.step, dst.cols, dst.rows, wsz.width, wsz.height, ofs.x, ofs.y);
} }
......
...@@ -1079,49 +1079,38 @@ namespace cv ...@@ -1079,49 +1079,38 @@ namespace cv
// ===== 1. replacement implementation // ===== 1. replacement implementation
struct ReplacementMorphImpl : public hal::Morph static bool halMorph(int op, int src_type, int dst_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2,
int kernel_type, uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool isSubmatrix)
{ {
cvhalFilter2D * ctx; cvhalFilter2D * ctx;
bool isInitialized; int res = cv_hal_morphInit(&ctx, op, src_type, dst_type, width, height,
bool init(int op, int src_type, int dst_type, int max_width, int max_height,
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
int borderType, const double borderValue[4],
int iterations, bool isSubmatrix, bool allowInplace)
{
int res = cv_hal_morphInit(&ctx, op, src_type, dst_type, max_width, max_height,
kernel_type, kernel_data, kernel_step, kernel_width, kernel_height, kernel_type, kernel_data, kernel_step, kernel_width, kernel_height,
anchor_x, anchor_y, anchor_x, anchor_y,
borderType, borderValue, borderType, borderValue,
iterations, isSubmatrix, allowInplace); iterations, isSubmatrix, src_data == dst_data);
isInitialized = (res == CV_HAL_ERROR_OK); if (res != CV_HAL_ERROR_OK)
return isInitialized; return false;
}
void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, res = cv_hal_morph(ctx, src_data, src_step, dst_data, dst_step, width, height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2)
{
if (isInitialized)
{
int res = cv_hal_morph(ctx, src_data, src_step, dst_data, dst_step, width, height,
roi_width, roi_height, roi_width, roi_height,
roi_x, roi_y, roi_x, roi_y,
roi_width2, roi_height2, roi_width2, roi_height2,
roi_x2, roi_y2); roi_x2, roi_y2);
bool success = (res == CV_HAL_ERROR_OK);
res = cv_hal_morphFree(ctx);
if (res != CV_HAL_ERROR_OK) if (res != CV_HAL_ERROR_OK)
CV_Error(Error::StsNotImplemented, "Failed to run HAL morph implementation"); return false;
}
} return success;
~ReplacementMorphImpl() }
{
if (isInitialized)
{
int res = cv_hal_morphFree(ctx);
if (res != CV_HAL_ERROR_OK)
CV_Error(Error::StsNotImplemented, "Failed to run HAL morph implementation");
}
}
};
// ===== 2. IPP implementation // ===== 2. IPP implementation
...@@ -1133,7 +1122,7 @@ template <int cvtype> struct IppMorphTrait {}; ...@@ -1133,7 +1122,7 @@ template <int cvtype> struct IppMorphTrait {};
#if IPP_VERSION_X100 >= 900 #if IPP_VERSION_X100 >= 900
#define INIT_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\ #define DEFINE_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\ template <>\
struct IppMorphTrait<cvtype>\ struct IppMorphTrait<cvtype>\
{\ {\
...@@ -1153,7 +1142,7 @@ struct IppMorphTrait<cvtype>\ ...@@ -1153,7 +1142,7 @@ struct IppMorphTrait<cvtype>\
#else #else
#define INIT_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\ #define DEFINE_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\ template <>\
struct IppMorphTrait<cvtype>\ struct IppMorphTrait<cvtype>\
{\ {\
...@@ -1173,28 +1162,28 @@ struct IppMorphTrait<cvtype>\ ...@@ -1173,28 +1162,28 @@ struct IppMorphTrait<cvtype>\
#endif #endif
INIT_TRAIT(CV_8UC1, 8u, 8u_C1R, 1, zero = 0) DEFINE_TRAIT(CV_8UC1, 8u, 8u_C1R, 1, zero = 0)
INIT_TRAIT(CV_8UC3, 8u, 8u_C3R, 3, zero[3] = {0}) DEFINE_TRAIT(CV_8UC3, 8u, 8u_C3R, 3, zero[3] = {0})
INIT_TRAIT(CV_8UC4, 8u, 8u_C4R, 4, zero[4] = {0}) DEFINE_TRAIT(CV_8UC4, 8u, 8u_C4R, 4, zero[4] = {0})
INIT_TRAIT(CV_32FC1, 32f, 32f_C1R, 1, zero = 0) DEFINE_TRAIT(CV_32FC1, 32f, 32f_C1R, 1, zero = 0)
INIT_TRAIT(CV_32FC3, 32f, 32f_C3R, 3, zero[3] = {0}) DEFINE_TRAIT(CV_32FC3, 32f, 32f_C3R, 3, zero[3] = {0})
INIT_TRAIT(CV_32FC4, 32f, 32f_C4R, 4, zero[4] = {0}) DEFINE_TRAIT(CV_32FC4, 32f, 32f_C4R, 4, zero[4] = {0})
#undef INIT_TRAIT #undef DEFINE_TRAIT
//-------------------------------------- //--------------------------------------
struct IppMorphBaseImpl : public hal::Morph
{
virtual bool init(int _op, int _src_type, int dst_type, int max_width, int max_height,
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
int borderType, const double borderValue[4],
int iterations, bool isSubmatrix, bool allowInplace) = 0;
};
template <int cvtype> template <int cvtype>
struct IppMorphImpl : public IppMorphBaseImpl static bool ippMorph(int op, int src_type, int dst_type,
const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2,
int kernel_type, uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool isSubmatrix)
{ {
IppMorphTrait<cvtype> trait; IppMorphTrait<cvtype> trait;
typedef typename IppMorphTrait<cvtype>::ipp_data_type ipp_data_type; typedef typename IppMorphTrait<cvtype>::ipp_data_type ipp_data_type;
...@@ -1203,20 +1192,14 @@ struct IppMorphImpl : public IppMorphBaseImpl ...@@ -1203,20 +1192,14 @@ struct IppMorphImpl : public IppMorphBaseImpl
IppiSize kernelSize; IppiSize kernelSize;
bool rectKernel; bool rectKernel;
IppiPoint anchor; IppiPoint anchor;
int op;
int src_type;
int border;
bool init(int _op, int _src_type, int dst_type, int max_width, int max_height, CV_INSTRUMENT_REGION_IPP()
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height,
int anchor_x, int anchor_y, CV_UNUSED(roi_width); CV_UNUSED(roi_height); CV_UNUSED(roi_x); CV_UNUSED(roi_y);
int borderType, const double borderValue[4], CV_UNUSED(roi_width2); CV_UNUSED(roi_height2); CV_UNUSED(roi_x2); CV_UNUSED(roi_y2);
int iterations, bool isSubmatrix, bool allowInplace)
{
border = borderType; // TODO: remove
anchor = ippiPoint(anchor_x, anchor_y);
CV_UNUSED(dst_type); CV_UNUSED(dst_type);
src_type = _src_type;
anchor = ippiPoint(anchor_x, anchor_y);
Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step); Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type); int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type);
...@@ -1227,7 +1210,7 @@ struct IppMorphImpl : public IppMorphBaseImpl ...@@ -1227,7 +1210,7 @@ struct IppMorphImpl : public IppMorphBaseImpl
|| (borderType == cv::BORDER_CONSTANT && Vec<double, 4>(borderValue) == morphologyDefaultBorderValue() && kernel.size() == Size(3,3))) || (borderType == cv::BORDER_CONSTANT && Vec<double, 4>(borderValue) == morphologyDefaultBorderValue() && kernel.size() == Size(3,3)))
|| !( op == MORPH_DILATE || op == MORPH_ERODE) || !( op == MORPH_DILATE || op == MORPH_ERODE)
|| isSubmatrix || isSubmatrix
|| allowInplace) || src_data == dst_data)
return false; return false;
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only // In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
...@@ -1281,9 +1264,8 @@ struct IppMorphImpl : public IppMorphBaseImpl ...@@ -1281,9 +1264,8 @@ struct IppMorphImpl : public IppMorphBaseImpl
if( iterations > 1 ) if( iterations > 1 )
return false; return false;
IppiSize roiSize = {max_width, max_height}; IppiSize roiSize = {width, height};
kernelSize = ippiSize(ksize); kernelSize = ippiSize(ksize);
op = _op;
IppStatus res; IppStatus res;
if (!rectKernel) if (!rectKernel)
...@@ -1297,8 +1279,8 @@ struct IppMorphImpl : public IppMorphBaseImpl ...@@ -1297,8 +1279,8 @@ struct IppMorphImpl : public IppMorphBaseImpl
specBuf.Alloc(specSize); specBuf.Alloc(specSize);
workBuf.Alloc(bufferSize); workBuf.Alloc(bufferSize);
res = trait.morphInit(roiSize, kernel.ptr(), kernelSize, specBuf, workBuf); res = trait.morphInit(roiSize, kernel.ptr(), kernelSize, specBuf, workBuf);
if (res >= 0) if (res < 0)
return true; return false;
} }
} }
else else
...@@ -1310,39 +1292,21 @@ struct IppMorphImpl : public IppMorphBaseImpl ...@@ -1310,39 +1292,21 @@ struct IppMorphImpl : public IppMorphBaseImpl
int bufSize = 0; int bufSize = 0;
res = trait.filterGetMinSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize); res = trait.filterGetMinSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
if (res >= 0) if (res >= 0)
{
workBuf.Alloc(bufSize); workBuf.Alloc(bufSize);
return true; else
} return false;
} }
else else
{ {
int bufSize = 0; int bufSize = 0;
res = trait.filterGetMaxSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize); res = trait.filterGetMaxSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
if (res >= 0) if (res >= 0)
{
workBuf.Alloc(bufSize); workBuf.Alloc(bufSize);
return true; else
}
}
}
return false; return false;
} }
}
void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2)
{
CV_INSTRUMENT_REGION_IPP()
CV_UNUSED(roi_width); CV_UNUSED(roi_height); CV_UNUSED(roi_x); CV_UNUSED(roi_y);
CV_UNUSED(roi_width2); CV_UNUSED(roi_height2); CV_UNUSED(roi_x2); CV_UNUSED(roi_y2);
if (src_data == dst_data)
CV_Error(Error::StsBadArg, "IPP Morph inplace is not alowed");
IppiSize roiSize = {width, height};
IppStatus res;
if (!rectKernel) if (!rectKernel)
{ {
if (op == MORPH_ERODE) if (op == MORPH_ERODE)
...@@ -1357,23 +1321,7 @@ struct IppMorphImpl : public IppMorphBaseImpl ...@@ -1357,23 +1321,7 @@ struct IppMorphImpl : public IppMorphBaseImpl
else else
res = (trait.filterMaxBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf)); res = (trait.filterMaxBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf));
} }
if (res < 0) return res >= 0;
CV_Error(Error::StsBadArg, "Failed to run IPP morph");
}
};
static IppMorphBaseImpl * createIppImpl(int type)
{
switch (type)
{
case CV_8UC1: return new IppMorphImpl<CV_8UC1>();
case CV_8UC3: return new IppMorphImpl<CV_8UC3>();
case CV_8UC4: return new IppMorphImpl<CV_8UC4>();
case CV_32FC1: return new IppMorphImpl<CV_32FC1>();
case CV_32FC3: return new IppMorphImpl<CV_32FC3>();
case CV_32FC4: return new IppMorphImpl<CV_32FC4>();
}
return 0;
} }
#endif // IPP_VERSION_X100 >= 810 #endif // IPP_VERSION_X100 >= 810
...@@ -1381,32 +1329,20 @@ static IppMorphBaseImpl * createIppImpl(int type) ...@@ -1381,32 +1329,20 @@ static IppMorphBaseImpl * createIppImpl(int type)
// ===== 3. Fallback implementation // ===== 3. Fallback implementation
struct OcvMorphImpl : public hal::Morph static void ocvMorph(int op, int src_type, int dst_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2,
int kernel_type, uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations)
{ {
Ptr<FilterEngine> f;
int iterations;
int src_type;
int dst_type;
bool init(int op, int _src_type, int _dst_type, int, int,
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height,
int anchor_x, int anchor_y,
int borderType, const double _borderValue[4],
int _iterations, bool, bool)
{
iterations = _iterations;
src_type = _src_type;
dst_type = _dst_type;
Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step); Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
Point anchor(anchor_x, anchor_y); Point anchor(anchor_x, anchor_y);
Vec<double, 4> borderValue(_borderValue); Vec<double, 4> borderVal(borderValue);
f = createMorphologyFilter(op, src_type, kernel, anchor, borderType, borderType, borderValue ); Ptr<FilterEngine> f = createMorphologyFilter(op, src_type, kernel, anchor, borderType, borderType, borderVal);
return true;
}
void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2)
{
Mat src(Size(width, height), src_type, src_data, src_step); Mat src(Size(width, height), src_type, src_data, src_step);
Mat dst(Size(width, height), dst_type, dst_data, dst_step); Mat dst(Size(width, height), dst_type, dst_data, dst_step);
{ {
...@@ -1420,55 +1356,81 @@ struct OcvMorphImpl : public hal::Morph ...@@ -1420,55 +1356,81 @@ struct OcvMorphImpl : public hal::Morph
for( int i = 1; i < iterations; i++ ) for( int i = 1; i < iterations; i++ )
f->apply( dst, dst, wsz, ofs ); f->apply( dst, dst, wsz, ofs );
} }
} }
};
// ===== HAL interface implementation // ===== HAL interface implementation
namespace hal { namespace hal {
Ptr<Morph> Morph ::create(int op, int src_type, int dst_type, int max_width, int max_height,
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height, CV_DEPRECATED Ptr<Morph> Morph::create(int , int , int , int , int ,
int anchor_x, int anchor_y, int , uchar * , size_t ,
int borderType, const double borderValue[4], int , int ,
int iterations, bool isSubmatrix, bool allowInplace) int , int ,
int , const double *,
int , bool , bool ) { return Ptr<hal::Morph>(); }
void morph(int op, int src_type, int dst_type,
uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int roi_width, int roi_height, int roi_x, int roi_y,
int roi_width2, int roi_height2, int roi_x2, int roi_y2,
int kernel_type, uchar * kernel_data, size_t kernel_step,
int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool isSubmatrix)
{ {
{ {
ReplacementMorphImpl * impl = new ReplacementMorphImpl(); bool res = halMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
if (impl->init(op, src_type, dst_type, max_width, max_height, roi_width, roi_height, roi_x, roi_y,
kernel_type, kernel_data, kernel_step, kernel_width, kernel_height, roi_width2, roi_height2, roi_x2, roi_y2,
anchor_x, anchor_y, kernel_type, kernel_data, kernel_step,
borderType, borderValue, iterations, isSubmatrix, allowInplace)) kernel_width, kernel_height, anchor_x, anchor_y,
{ borderType, borderValue, iterations, isSubmatrix);
return Ptr<Morph>(impl); if (res)
} return;
delete impl;
} }
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 810 #if defined(HAVE_IPP) && IPP_VERSION_X100 >= 810
#define ONE_CASE(type) \
case type: \
res = ippMorph<type>(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height, \
roi_width, roi_height, roi_x, roi_y, \
roi_width2, roi_height2, roi_x2, roi_y2, \
kernel_type, kernel_data, kernel_step, \
kernel_width, kernel_height, anchor_x, anchor_y, \
borderType, borderValue, iterations, isSubmatrix); \
break;
CV_IPP_CHECK() CV_IPP_CHECK()
{ {
IppMorphBaseImpl * impl = createIppImpl(src_type); bool res = false;
if (impl) switch (src_type)
{ {
if (impl->init(op, src_type, dst_type, max_width, max_height, ONE_CASE(CV_8UC1)
kernel_type, kernel_data, kernel_step, kernel_width, kernel_height, ONE_CASE(CV_8UC3)
anchor_x, anchor_y, ONE_CASE(CV_8UC4)
borderType, borderValue, iterations, isSubmatrix, allowInplace)) ONE_CASE(CV_32FC1)
{ ONE_CASE(CV_32FC3)
return Ptr<Morph>(impl); ONE_CASE(CV_32FC4)
}
delete impl;
} }
if (res)
return;
} }
#undef ONE_CASE
#endif #endif
{
OcvMorphImpl * impl = new OcvMorphImpl(); ocvMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
impl->init(op, src_type, dst_type, max_width, max_height, roi_width, roi_height, roi_x, roi_y,
kernel_type, kernel_data, kernel_step, kernel_width, kernel_height, roi_width2, roi_height2, roi_x2, roi_y2,
anchor_x, anchor_y, kernel_type, kernel_data, kernel_step,
borderType, borderValue, iterations, isSubmatrix, allowInplace); kernel_width, kernel_height, anchor_x, anchor_y,
return Ptr<Morph>(impl); borderType, borderValue, iterations);
}
} }
} // cv::hal } // cv::hal
...@@ -1941,13 +1903,15 @@ static void morphOp( int op, InputArray _src, OutputArray _dst, ...@@ -1941,13 +1903,15 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
dst.locateROI(d_wsz, d_ofs); dst.locateROI(d_wsz, d_ofs);
} }
Ptr<hal::Morph> ctx = hal::Morph::create(op, src.type(), dst.type(), src.cols, src.rows, hal::morph(op, src.type(), dst.type(),
kernel.type(), kernel.data, kernel.step, kernel.cols, kernel.rows, src.data, src.step,
anchor.x, anchor.y, borderType, borderValue.val, iterations, dst.data, dst.step,
(src.isSubmatrix() && !isolated), src.data == dst.data); src.cols, src.rows,
ctx->apply(src.data, src.step, dst.data, dst.step, src.cols, src.rows,
s_wsz.width, s_wsz.height, s_ofs.x, s_ofs.y, s_wsz.width, s_wsz.height, s_ofs.x, s_ofs.y,
d_wsz.width, d_wsz.height, d_ofs.x, d_ofs.y); d_wsz.width, d_wsz.height, d_ofs.x, d_ofs.y,
kernel.type(), kernel.data, kernel.step, kernel.cols, kernel.rows, anchor.x, anchor.y,
borderType, borderValue.val, iterations,
(src.isSubmatrix() && !isolated));
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment