mirror of
https://github.com/opencv/opencv.git
synced 2024-11-29 13:47:32 +08:00
Merge pull request #7996 from mshabunin:hal-filter-revert
This commit is contained in:
commit
b46364e436
@ -10,53 +10,93 @@ 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 kernel_width, int kernel_height,
|
int , int ,
|
||||||
int anchor_x, int anchor_y,
|
int , int ,
|
||||||
int borderType, const double borderValue[4],
|
int , const double *,
|
||||||
int iterations, bool isSubmatrix, bool allowInplace);
|
int , bool , bool );
|
||||||
virtual void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
|
virtual void apply(uchar * , size_t , uchar * , size_t , int , int ,
|
||||||
int roi_width, int roi_height, int roi_x, int roi_y,
|
int , int , int , int ,
|
||||||
int roi_width2, int roi_height2, int roi_x2, int roi_y2) = 0;
|
int , int , int , int ) = 0;
|
||||||
virtual ~Morph() {}
|
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 anchor_x, int anchor_y,
|
||||||
|
double delta, int borderType,
|
||||||
|
bool isSubmatrix);
|
||||||
|
|
||||||
|
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_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);
|
||||||
|
|
||||||
|
|
||||||
CV_EXPORTS void resize(int src_type,
|
CV_EXPORTS void resize(int src_type,
|
||||||
const uchar * src_data, size_t src_step, int src_width, int src_height,
|
const uchar * src_data, size_t src_step, int src_width, int src_height,
|
||||||
|
@ -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,
|
if (res != CV_HAL_ERROR_OK)
|
||||||
int kernel_height, int max_width, int max_height, int stype, int dtype, int borderType, double delta,
|
return false;
|
||||||
int anchor_x, int anchor_y, bool isSubmatrix, bool isInplace)
|
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);
|
||||||
int res = cv_hal_filterInit(&ctx, kernel_data, kernel_step, kernel_type, kernel_width, kernel_height, max_width, max_height,
|
res = cv_hal_filterFree(ctx);
|
||||||
stype, dtype, borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace);
|
if (res != CV_HAL_ERROR_OK)
|
||||||
isInitialized = (res == CV_HAL_ERROR_OK);
|
return false;
|
||||||
return isInitialized;
|
return success;
|
||||||
}
|
}
|
||||||
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)
|
|
||||||
CV_Error(Error::StsNotImplemented, "HAL Filter returned an error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~ReplacementFilter()
|
|
||||||
{
|
|
||||||
if (isInitialized)
|
|
||||||
{
|
|
||||||
int res = cv_hal_filterFree(ctx);
|
|
||||||
if (res != CV_HAL_ERROR_OK)
|
|
||||||
CV_Error(Error::StsNotImplemented, "HAL Filter Free returned an error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef HAVE_IPP
|
#ifdef HAVE_IPP
|
||||||
typedef IppStatus(CV_STDCALL* IppiFilterBorder)(
|
typedef IppStatus(CV_STDCALL* IppiFilterBorder)(
|
||||||
@ -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,105 +4623,92 @@ 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,
|
Point anchor(anchor_x, anchor_y);
|
||||||
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);
|
|
||||||
#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);
|
||||||
#else
|
#else
|
||||||
Point ippAnchor(kernel_width >> 1, kernel_height >> 1);
|
Point ippAnchor(kernel_width >> 1, kernel_height >> 1);
|
||||||
#endif
|
#endif
|
||||||
bool isIsolated = (borderType & BORDER_ISOLATED) != 0;
|
bool isIsolated = (borderType & BORDER_ISOLATED) != 0;
|
||||||
int borderTypeNI = borderType & ~BORDER_ISOLATED;
|
int borderTypeNI = borderType & ~BORDER_ISOLATED;
|
||||||
ippBorderType = ippiGetBorderType(borderTypeNI);
|
ippBorderType = ippiGetBorderType(borderTypeNI);
|
||||||
int ddepth = CV_MAT_DEPTH(dtype);
|
int ddepth = CV_MAT_DEPTH(dtype);
|
||||||
int sdepth = CV_MAT_DEPTH(stype);
|
int sdepth = CV_MAT_DEPTH(stype);
|
||||||
|
|
||||||
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 < 201702 // IPP bug with 1x1 kernel
|
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 < 201702 // IPP bug with 1x1 kernel
|
||||||
if(kernel_width == 1 && kernel_height == 1)
|
if(kernel_width == 1 && kernel_height == 1)
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool runIpp = true
|
bool runIpp = true
|
||||||
&& (borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE)
|
&& (borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE)
|
||||||
&& (sdepth == ddepth)
|
&& (sdepth == ddepth)
|
||||||
&& (getIppFunc(stype))
|
&& (getIppFunc(stype))
|
||||||
&& ((int)ippBorderType > 0)
|
&& ((int)ippBorderType > 0)
|
||||||
&& (!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;
|
||||||
|
|
||||||
src_type = stype;
|
src_type = stype;
|
||||||
int cn = CV_MAT_CN(stype);
|
int cn = CV_MAT_CN(stype);
|
||||||
IppiSize kernelSize = { kernel_width, kernel_height };
|
IppiSize kernelSize = { kernel_width, kernel_height };
|
||||||
IppDataType dataType = ippiGetDataType(ddepth);
|
IppDataType dataType = ippiGetDataType(ddepth);
|
||||||
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)
|
||||||
kernel_type* pKerBuffer = (kernel_type*)kernel_data;
|
return false;
|
||||||
size_t good_kernel_step = sizeof(kernel_type) * static_cast<size_t>(kernelSize.width);
|
|
||||||
|
kernel_type* pKerBuffer = (kernel_type*)kernel_data;
|
||||||
|
size_t good_kernel_step = sizeof(kernel_type) * static_cast<size_t>(kernelSize.width);
|
||||||
#if IPP_VERSION_X100 >= 900
|
#if IPP_VERSION_X100 >= 900
|
||||||
if (kernel_step != good_kernel_step) {
|
if (kernel_step != good_kernel_step) {
|
||||||
kernelBuffer.Alloc((int)good_kernel_step * kernelSize.height);
|
kernelBuffer.Alloc((int)good_kernel_step * kernelSize.height);
|
||||||
status = trait::get_copy_fun()((kernel_type*)kernel_data, (int)kernel_step, kernelBuffer, (int)good_kernel_step, kernelSize);
|
status = trait::get_copy_fun()((kernel_type*)kernel_data, (int)kernel_step, kernelBuffer, (int)good_kernel_step, kernelSize);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return false;
|
return false;
|
||||||
pKerBuffer = kernelBuffer;
|
pKerBuffer = kernelBuffer;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
kernelBuffer.Alloc(good_kernel_step * kernelSize.height);
|
kernelBuffer.Alloc(good_kernel_step * kernelSize.height);
|
||||||
Mat kerFlip(Size(kernelSize.width, kernelSize.height), trait::kernel_type_id, kernelBuffer, (int)good_kernel_step);
|
Mat kerFlip(Size(kernelSize.width, kernelSize.height), trait::kernel_type_id, kernelBuffer, (int)good_kernel_step);
|
||||||
Mat kernel(Size(kernel_width, kernel_height), trait::kernel_type_id, kernel_data, kernel_step);
|
Mat kernel(Size(kernel_width, kernel_height), trait::kernel_type_id, kernel_data, kernel_step);
|
||||||
flip(kernel, kerFlip, -1);
|
flip(kernel, kerFlip, -1);
|
||||||
pKerBuffer = kernelBuffer;
|
pKerBuffer = kernelBuffer;
|
||||||
#endif
|
#endif
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
IppiFilterBorder ippiFilterBorder = getIppFunc(src_type);
|
||||||
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int, int, int, int)
|
kernel_type borderValue[4] = { 0, 0, 0, 0 };
|
||||||
{
|
status = CV_INSTRUMENT_FUN_IPP(ippiFilterBorder, src_data, (int)src_step, dst_data, (int)dst_step, dstRoiSize, ippBorderType, borderValue, spec, buffer);
|
||||||
CV_INSTRUMENT_REGION_IPP()
|
if (status >= 0) {
|
||||||
|
CV_IMPL_ADD(CV_IMPL_IPP);
|
||||||
if (dst_data == src_data)
|
return true;
|
||||||
CV_Error(Error::StsBadArg, "Inplace IPP Filter2D is not supported");
|
|
||||||
IppiFilterBorder ippiFilterBorder = getIppFunc(src_type);
|
|
||||||
IppiSize dstRoiSize = { width, height };
|
|
||||||
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);
|
|
||||||
if (status >= 0) {
|
|
||||||
CV_IMPL_ADD(CV_IMPL_IPP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
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,162 +4719,112 @@ 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)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height,
|
Point anchor = Point(anchor_x, anchor_y);
|
||||||
int, int, int stype, int dtype,
|
Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply(uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int, int, int, int)
|
Mat src(Size(width, height), stype, src_data, src_step);
|
||||||
{
|
Mat dst(Size(width, height), dtype, dst_data, dst_step);
|
||||||
Mat src(Size(width, height), src_type, src_data, src_step);
|
Mat temp;
|
||||||
Mat dst(Size(width, height), dst_type, dst_data, dst_step);
|
int src_channels = CV_MAT_CN(stype);
|
||||||
Mat temp;
|
int dst_channels = CV_MAT_CN(dtype);
|
||||||
int src_channels = CV_MAT_CN(src_type);
|
int ddepth = CV_MAT_DEPTH(dtype);
|
||||||
int dst_channels = CV_MAT_CN(dst_type);
|
// crossCorr doesn't accept non-zero delta with multiple channels
|
||||||
int ddepth = CV_MAT_DEPTH(dst_type);
|
if (src_channels != 1 && delta != 0) {
|
||||||
// crossCorr doesn't accept non-zero delta with multiple channels
|
// The semantics of filter2D require that the delta be applied
|
||||||
if (src_channels != 1 && delta != 0) {
|
// as floating-point math. So wee need an intermediate Mat
|
||||||
// The semantics of filter2D require that the delta be applied
|
// with a float datatype. If the dest is already floats,
|
||||||
// as floating-point math. So wee need an intermediate Mat
|
// we just use that.
|
||||||
// with a float datatype. If the dest is already floats,
|
int corrDepth = ddepth;
|
||||||
// we just use that.
|
if ((ddepth == CV_32F || ddepth == CV_64F) && src_data != dst_data) {
|
||||||
int corrDepth = ddepth;
|
temp = Mat(Size(width, height), dtype, dst_data, dst_step);
|
||||||
if ((ddepth == CV_32F || ddepth == CV_64F) && src_data != dst_data) {
|
|
||||||
temp = Mat(Size(width, height), dst_type, dst_data, dst_step);
|
|
||||||
} else {
|
|
||||||
corrDepth = ddepth == CV_64F ? CV_64F : CV_32F;
|
|
||||||
temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels));
|
|
||||||
}
|
|
||||||
crossCorr(src, kernel, temp, src.size(),
|
|
||||||
CV_MAKETYPE(corrDepth, src_channels),
|
|
||||||
anchor, 0, borderType);
|
|
||||||
add(temp, delta, temp);
|
|
||||||
if (temp.data != dst_data) {
|
|
||||||
temp.convertTo(dst, dst.type());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (src_data != dst_data)
|
corrDepth = ddepth == CV_64F ? CV_64F : CV_32F;
|
||||||
temp = Mat(Size(width, height), dst_type, dst_data, dst_step);
|
temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels));
|
||||||
else
|
|
||||||
temp.create(Size(width, height), dst_type);
|
|
||||||
crossCorr(src, kernel, temp, src.size(),
|
|
||||||
CV_MAKETYPE(ddepth, src_channels),
|
|
||||||
anchor, delta, borderType);
|
|
||||||
if (temp.data != dst_data)
|
|
||||||
temp.copyTo(dst);
|
|
||||||
}
|
}
|
||||||
|
crossCorr(src, kernel, temp, src.size(),
|
||||||
|
CV_MAKETYPE(corrDepth, src_channels),
|
||||||
|
anchor, 0, borderType);
|
||||||
|
add(temp, delta, temp);
|
||||||
|
if (temp.data != dst_data) {
|
||||||
|
temp.convertTo(dst, dst.type());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (src_data != dst_data)
|
||||||
|
temp = Mat(Size(width, height), dtype, dst_data, dst_step);
|
||||||
|
else
|
||||||
|
temp.create(Size(width, height), dtype);
|
||||||
|
crossCorr(src, kernel, temp, src.size(),
|
||||||
|
CV_MAKETYPE(ddepth, src_channels),
|
||||||
|
anchor, delta, borderType);
|
||||||
|
if (temp.data != dst_data)
|
||||||
|
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 borderTypeValue = borderType & ~BORDER_ISOLATED;
|
||||||
int src_type;
|
Mat kernel = Mat(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
|
||||||
int dst_type;
|
Ptr<FilterEngine> f = createLinearFilter(stype, dtype, kernel, Point(anchor_x, anchor_y), delta,
|
||||||
bool isIsolated;
|
borderTypeValue);
|
||||||
|
Mat src(Size(width, height), stype, src_data, src_step);
|
||||||
|
Mat dst(Size(width, height), dtype, dst_data, dst_step);
|
||||||
|
f->apply(src, dst, Size(full_width, full_height), Point(offset_x, offset_y));
|
||||||
|
}
|
||||||
|
|
||||||
bool init(uchar* kernel_data, size_t kernel_step, int kernel_type, int kernel_width,
|
static bool replacementSepFilter(int stype, int dtype, int ktype,
|
||||||
int kernel_height, int, int, int stype, int dtype, int borderType, double delta,
|
uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
|
||||||
int anchor_x, int anchor_y, bool, bool)
|
int width, int height, int full_width, int full_height,
|
||||||
{
|
int offset_x, int offset_y,
|
||||||
isIsolated = (borderType & BORDER_ISOLATED) != 0;
|
uchar * kernelx_data, int kernelx_len,
|
||||||
src_type = stype;
|
uchar * kernely_data, int kernely_len,
|
||||||
dst_type = dtype;
|
int anchor_x, int anchor_y, double delta, int borderType)
|
||||||
int borderTypeValue = borderType & ~BORDER_ISOLATED;
|
|
||||||
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,
|
|
||||||
borderTypeValue);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ReplacementSepFilter : public hal::SepFilter2D
|
|
||||||
{
|
{
|
||||||
cvhalFilter2D *ctx;
|
cvhalFilter2D *ctx;
|
||||||
bool isInitialized;
|
int res = cv_hal_sepFilterInit(&ctx, stype, dtype, ktype,
|
||||||
ReplacementSepFilter() : ctx(0), isInitialized(false) {}
|
kernelx_data, kernelx_len,
|
||||||
bool init(int stype, int dtype, int ktype,
|
kernely_data, kernely_len,
|
||||||
uchar * kernelx_data, int kernelx_len,
|
anchor_x, anchor_y, delta, borderType);
|
||||||
uchar * kernely_data, int kernely_len,
|
if (res != CV_HAL_ERROR_OK)
|
||||||
int anchor_x, int anchor_y, double delta, int borderType)
|
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);
|
||||||
int res = cv_hal_sepFilterInit(&ctx, stype, dtype, ktype,
|
bool success = (res == CV_HAL_ERROR_OK);
|
||||||
kernelx_data, kernelx_len,
|
res = cv_hal_sepFilterFree(ctx);
|
||||||
kernely_data, kernely_len,
|
if (res != CV_HAL_ERROR_OK)
|
||||||
anchor_x, anchor_y, delta, borderType);
|
return false;
|
||||||
isInitialized = (res == CV_HAL_ERROR_OK);
|
return success;
|
||||||
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)
|
|
||||||
CV_Error(Error::StsNotImplemented, "Failed to run HAL sepFilter implementation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~ReplacementSepFilter()
|
|
||||||
{
|
|
||||||
if (isInitialized)
|
|
||||||
{
|
|
||||||
int res = cv_hal_sepFilterFree(ctx);
|
|
||||||
if (res != CV_HAL_ERROR_OK)
|
|
||||||
CV_Error(Error::StsNotImplemented, "Failed to run HAL sepFilter implementation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
Ptr<FilterEngine> f;
|
Mat kernelX(Size(kernelx_len, 1), ktype, kernelx_data);
|
||||||
int src_type;
|
Mat kernelY(Size(kernely_len, 1), ktype, kernely_data);
|
||||||
int dst_type;
|
Ptr<FilterEngine> f = createSeparableLinearFilter(stype, dtype, kernelX, kernelY,
|
||||||
bool init(int stype, int dtype, int ktype,
|
Point(anchor_x, anchor_y),
|
||||||
uchar * kernelx_data, int kernelx_len,
|
delta, borderType & ~BORDER_ISOLATED);
|
||||||
uchar * kernely_data, int kernely_len,
|
Mat src(Size(width, height), stype, src_data, src_step);
|
||||||
int anchor_x, int anchor_y, double delta, int borderType)
|
Mat dst(Size(width, height), dtype, dst_data, dst_step);
|
||||||
{
|
f->apply(src, dst, Size(full_width, full_height), Point(offset_x, offset_y));
|
||||||
src_type = stype;
|
|
||||||
dst_type = dtype;
|
|
||||||
Mat kernelX(Size(kernelx_len, 1), ktype, kernelx_data);
|
|
||||||
Mat kernelY(Size(kernely_len, 1), ktype, kernely_data);
|
|
||||||
|
|
||||||
f = createSeparableLinearFilter( stype, dtype, kernelX, kernelY,
|
|
||||||
Point(anchor_x, anchor_y),
|
|
||||||
delta, borderType & ~BORDER_ISOLATED );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//===================================================================
|
//===================================================================
|
||||||
@ -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,
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
ReplacementFilter* impl = new ReplacementFilter();
|
|
||||||
if (impl->init(kernel_data, kernel_step, kernel_type, kernel_width, kernel_height,
|
|
||||||
max_width, max_height, stype, dtype,
|
|
||||||
borderType, delta, anchor_x, anchor_y, isSubmatrix, isInplace))
|
|
||||||
{
|
|
||||||
return Ptr<hal::Filter2D>(impl);
|
|
||||||
}
|
|
||||||
delete impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 anchor_x, int anchor_y,
|
||||||
|
double delta, int borderType,
|
||||||
|
bool isSubmatrix)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
res = replacementFilter2D(stype, dtype, kernel_type,
|
||||||
|
src_data, src_step,
|
||||||
|
dst_data, dst_step,
|
||||||
|
width, height,
|
||||||
|
full_width, full_height,
|
||||||
|
offset_x, offset_y,
|
||||||
|
kernel_data, kernel_step,
|
||||||
|
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 * kernelx_data, int kernelx_len,
|
uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step,
|
||||||
uchar * kernely_data, int kernely_len,
|
int width, int height, int full_width, int full_height,
|
||||||
int anchor_x, int anchor_y, double delta, int borderType)
|
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)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
ReplacementSepFilter * impl = new ReplacementSepFilter();
|
bool res = replacementSepFilter(stype, dtype, ktype,
|
||||||
if (impl->init(stype, dtype, ktype,
|
src_data, src_step, dst_data, dst_step,
|
||||||
kernelx_data, kernelx_len,
|
width, height, full_width, full_height,
|
||||||
kernely_data, kernely_len,
|
offset_x, offset_y,
|
||||||
anchor_x, anchor_y, delta, borderType))
|
kernelx_data, kernelx_len,
|
||||||
{
|
kernely_data, kernely_len,
|
||||||
return Ptr<hal::SepFilter2D>(impl);
|
anchor_x, anchor_y, delta, borderType);
|
||||||
}
|
if (res)
|
||||||
delete impl;
|
return;
|
||||||
}
|
ocvSepFilter(stype, dtype, ktype,
|
||||||
{
|
src_data, src_step, dst_data, dst_step,
|
||||||
OcvSepFilter * impl = new OcvSepFilter();
|
width, height, full_width, full_height,
|
||||||
impl->init(stype, dtype, ktype,
|
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);
|
||||||
return Ptr<hal::SepFilter2D>(impl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // cv::hal::
|
} // cv::hal::
|
||||||
@ -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,
|
|||||||
|
|
||||||
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(),
|
|
||||||
contKernelX.data, kernelX.cols + kernelX.rows - 1,
|
hal::sepFilter2D(src.type(), dst.type(), kernelX.type(),
|
||||||
contKernelY.data, kernelY.cols + kernelY.rows - 1,
|
src.data, src.step, dst.data, dst.step,
|
||||||
anchor.x, anchor.y, delta, borderType & ~BORDER_ISOLATED);
|
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);
|
contKernelX.data, kernelX.cols + kernelX.rows - 1,
|
||||||
|
contKernelY.data, kernelY.cols + kernelY.rows - 1,
|
||||||
|
anchor.x, anchor.y, delta, borderType & ~BORDER_ISOLATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
kernel_type, kernel_data, kernel_step, kernel_width, kernel_height,
|
||||||
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height,
|
anchor_x, anchor_y,
|
||||||
int anchor_x, int anchor_y,
|
borderType, borderValue,
|
||||||
int borderType, const double borderValue[4],
|
iterations, isSubmatrix, src_data == dst_data);
|
||||||
int iterations, bool isSubmatrix, bool allowInplace)
|
if (res != CV_HAL_ERROR_OK)
|
||||||
{
|
return false;
|
||||||
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,
|
res = cv_hal_morph(ctx, src_data, src_step, dst_data, dst_step, width, height,
|
||||||
anchor_x, anchor_y,
|
roi_width, roi_height,
|
||||||
borderType, borderValue,
|
roi_x, roi_y,
|
||||||
iterations, isSubmatrix, allowInplace);
|
roi_width2, roi_height2,
|
||||||
isInitialized = (res == CV_HAL_ERROR_OK);
|
roi_x2, roi_y2);
|
||||||
return isInitialized;
|
bool success = (res == CV_HAL_ERROR_OK);
|
||||||
}
|
|
||||||
void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
|
res = cv_hal_morphFree(ctx);
|
||||||
int roi_width, int roi_height, int roi_x, int roi_y,
|
if (res != CV_HAL_ERROR_OK)
|
||||||
int roi_width2, int roi_height2, int roi_x2, int roi_y2)
|
return false;
|
||||||
{
|
|
||||||
if (isInitialized)
|
return success;
|
||||||
{
|
}
|
||||||
int res = cv_hal_morph(ctx, 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);
|
|
||||||
if (res != CV_HAL_ERROR_OK)
|
|
||||||
CV_Error(Error::StsNotImplemented, "Failed to run HAL morph implementation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~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 {};
|
|||||||
|
|
||||||
#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>\
|
|||||||
|
|
||||||
#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>\
|
|||||||
|
|
||||||
#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,177 +1192,136 @@ 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)
|
CV_UNUSED(dst_type);
|
||||||
|
|
||||||
|
anchor = ippiPoint(anchor_x, anchor_y);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if( !( depth == CV_8U || depth == CV_32F )
|
||||||
|
|| !(cn == 1 || cn == 3 || cn == 4)
|
||||||
|
|| !( borderType == cv::BORDER_REPLICATE
|
||||||
|
|| (borderType == cv::BORDER_CONSTANT && Vec<double, 4>(borderValue) == morphologyDefaultBorderValue() && kernel.size() == Size(3,3)))
|
||||||
|
|| !( op == MORPH_DILATE || op == MORPH_ERODE)
|
||||||
|
|| isSubmatrix
|
||||||
|
|| src_data == dst_data)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
|
||||||
|
if( borderType == cv::BORDER_CONSTANT && kernel.data )
|
||||||
{
|
{
|
||||||
border = borderType; // TODO: remove
|
int x, y;
|
||||||
anchor = ippiPoint(anchor_x, anchor_y);
|
for( y = 0; y < kernel.rows; y++ )
|
||||||
CV_UNUSED(dst_type);
|
|
||||||
src_type = _src_type;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if( !( depth == CV_8U || depth == CV_32F )
|
|
||||||
|| !(cn == 1 || cn == 3 || cn == 4)
|
|
||||||
|| !( borderType == cv::BORDER_REPLICATE
|
|
||||||
|| (borderType == cv::BORDER_CONSTANT && Vec<double, 4>(borderValue) == morphologyDefaultBorderValue() && kernel.size() == Size(3,3)))
|
|
||||||
|| !( op == MORPH_DILATE || op == MORPH_ERODE)
|
|
||||||
|| isSubmatrix
|
|
||||||
|| allowInplace)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
|
|
||||||
if( borderType == cv::BORDER_CONSTANT && kernel.data )
|
|
||||||
{
|
{
|
||||||
int x, y;
|
if( kernel.at<uchar>(y, anchor.x) != 0 )
|
||||||
for( y = 0; y < kernel.rows; y++ )
|
continue;
|
||||||
{
|
|
||||||
if( kernel.at<uchar>(y, anchor.x) != 0 )
|
|
||||||
continue;
|
|
||||||
for( x = 0; x < kernel.cols; x++ )
|
|
||||||
{
|
|
||||||
if( kernel.at<uchar>(y,x) != 0 )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for( x = 0; x < kernel.cols; x++ )
|
for( x = 0; x < kernel.cols; x++ )
|
||||||
{
|
{
|
||||||
if( kernel.at<uchar>(anchor.y, x) != 0 )
|
if( kernel.at<uchar>(y,x) != 0 )
|
||||||
continue;
|
return false;
|
||||||
for( y = 0; y < kernel.rows; y++ )
|
|
||||||
{
|
|
||||||
if( kernel.at<uchar>(y,x) != 0 )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
for( x = 0; x < kernel.cols; x++ )
|
||||||
Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
|
|
||||||
|
|
||||||
rectKernel = false;
|
|
||||||
if( kernel.empty() )
|
|
||||||
{
|
{
|
||||||
ksize = Size(1+iterations*2,1+iterations*2);
|
if( kernel.at<uchar>(anchor.y, x) != 0 )
|
||||||
anchor = ippiPoint(iterations, iterations);
|
continue;
|
||||||
rectKernel = true;
|
for( y = 0; y < kernel.rows; y++ )
|
||||||
iterations = 1;
|
|
||||||
}
|
|
||||||
else if( iterations >= 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
|
|
||||||
{
|
|
||||||
ksize = Size(ksize.width + (iterations-1)*(ksize.width-1),
|
|
||||||
ksize.height + (iterations-1)*(ksize.height-1)),
|
|
||||||
anchor = ippiPoint(anchor.x*iterations, anchor.y*iterations);
|
|
||||||
kernel = Mat();
|
|
||||||
rectKernel = true;
|
|
||||||
iterations = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement the case of iterations > 1.
|
|
||||||
if( iterations > 1 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
IppiSize roiSize = {max_width, max_height};
|
|
||||||
kernelSize = ippiSize(ksize);
|
|
||||||
op = _op;
|
|
||||||
|
|
||||||
IppStatus res;
|
|
||||||
if (!rectKernel)
|
|
||||||
{
|
|
||||||
if (((kernel.cols - 1) / 2 != anchor.x) || ((kernel.rows - 1) / 2 != anchor.y))
|
|
||||||
return false;
|
|
||||||
int specSize = 0, bufferSize = 0;
|
|
||||||
res = trait.getMorphSize(roiSize, kernelSize, &specSize, &bufferSize);
|
|
||||||
if (res >= 0)
|
|
||||||
{
|
{
|
||||||
specBuf.Alloc(specSize);
|
if( kernel.at<uchar>(y,x) != 0 )
|
||||||
workBuf.Alloc(bufferSize);
|
return false;
|
||||||
res = trait.morphInit(roiSize, kernel.ptr(), kernelSize, specBuf, workBuf);
|
|
||||||
if (res >= 0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (((kernelSize.width - 1) / 2 != anchor.x) || ((kernelSize.height - 1) / 2 != anchor.y))
|
|
||||||
return false;
|
|
||||||
if (op == MORPH_ERODE)
|
|
||||||
{
|
|
||||||
int bufSize = 0;
|
|
||||||
res = trait.filterGetMinSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
|
|
||||||
if (res >= 0)
|
|
||||||
{
|
|
||||||
workBuf.Alloc(bufSize);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int bufSize = 0;
|
|
||||||
res = trait.filterGetMaxSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
|
|
||||||
if (res >= 0)
|
|
||||||
{
|
|
||||||
workBuf.Alloc(bufSize);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
|
||||||
|
|
||||||
|
rectKernel = false;
|
||||||
|
if( kernel.empty() )
|
||||||
|
{
|
||||||
|
ksize = Size(1+iterations*2,1+iterations*2);
|
||||||
|
anchor = ippiPoint(iterations, iterations);
|
||||||
|
rectKernel = true;
|
||||||
|
iterations = 1;
|
||||||
|
}
|
||||||
|
else if( iterations >= 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
|
||||||
|
{
|
||||||
|
ksize = Size(ksize.width + (iterations-1)*(ksize.width-1),
|
||||||
|
ksize.height + (iterations-1)*(ksize.height-1)),
|
||||||
|
anchor = ippiPoint(anchor.x*iterations, anchor.y*iterations);
|
||||||
|
kernel = Mat();
|
||||||
|
rectKernel = true;
|
||||||
|
iterations = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement the case of iterations > 1.
|
||||||
|
if( iterations > 1 )
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
void apply(uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height,
|
IppiSize roiSize = {width, height};
|
||||||
int roi_width, int roi_height, int roi_x, int roi_y,
|
kernelSize = ippiSize(ksize);
|
||||||
int roi_width2, int roi_height2, int roi_x2, int roi_y2)
|
|
||||||
|
IppStatus res;
|
||||||
|
if (!rectKernel)
|
||||||
{
|
{
|
||||||
CV_INSTRUMENT_REGION_IPP()
|
if (((kernel.cols - 1) / 2 != anchor.x) || ((kernel.rows - 1) / 2 != anchor.y))
|
||||||
|
return false;
|
||||||
CV_UNUSED(roi_width); CV_UNUSED(roi_height); CV_UNUSED(roi_x); CV_UNUSED(roi_y);
|
int specSize = 0, bufferSize = 0;
|
||||||
CV_UNUSED(roi_width2); CV_UNUSED(roi_height2); CV_UNUSED(roi_x2); CV_UNUSED(roi_y2);
|
res = trait.getMorphSize(roiSize, kernelSize, &specSize, &bufferSize);
|
||||||
if (src_data == dst_data)
|
if (res >= 0)
|
||||||
CV_Error(Error::StsBadArg, "IPP Morph inplace is not alowed");
|
|
||||||
|
|
||||||
IppiSize roiSize = {width, height};
|
|
||||||
|
|
||||||
IppStatus res;
|
|
||||||
if (!rectKernel)
|
|
||||||
{
|
{
|
||||||
if (op == MORPH_ERODE)
|
specBuf.Alloc(specSize);
|
||||||
res = (trait.morphErode((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, specBuf, workBuf));
|
workBuf.Alloc(bufferSize);
|
||||||
|
res = trait.morphInit(roiSize, kernel.ptr(), kernelSize, specBuf, workBuf);
|
||||||
|
if (res < 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (((kernelSize.width - 1) / 2 != anchor.x) || ((kernelSize.height - 1) / 2 != anchor.y))
|
||||||
|
return false;
|
||||||
|
if (op == MORPH_ERODE)
|
||||||
|
{
|
||||||
|
int bufSize = 0;
|
||||||
|
res = trait.filterGetMinSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
|
||||||
|
if (res >= 0)
|
||||||
|
workBuf.Alloc(bufSize);
|
||||||
else
|
else
|
||||||
res = (trait.morphDilate((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, specBuf, workBuf));
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (op == MORPH_ERODE)
|
int bufSize = 0;
|
||||||
res = (trait.filterMinBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf));
|
res = trait.filterGetMaxSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
|
||||||
|
if (res >= 0)
|
||||||
|
workBuf.Alloc(bufSize);
|
||||||
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));
|
return false;
|
||||||
}
|
}
|
||||||
if (res < 0)
|
|
||||||
CV_Error(Error::StsBadArg, "Failed to run IPP morph");
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
static IppMorphBaseImpl * createIppImpl(int type)
|
if (!rectKernel)
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case CV_8UC1: return new IppMorphImpl<CV_8UC1>();
|
if (op == MORPH_ERODE)
|
||||||
case CV_8UC3: return new IppMorphImpl<CV_8UC3>();
|
res = (trait.morphErode((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, specBuf, workBuf));
|
||||||
case CV_8UC4: return new IppMorphImpl<CV_8UC4>();
|
else
|
||||||
case CV_32FC1: return new IppMorphImpl<CV_32FC1>();
|
res = (trait.morphDilate((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, specBuf, workBuf));
|
||||||
case CV_32FC3: return new IppMorphImpl<CV_32FC3>();
|
|
||||||
case CV_32FC4: return new IppMorphImpl<CV_32FC4>();
|
|
||||||
}
|
}
|
||||||
return 0;
|
else
|
||||||
|
{
|
||||||
|
if (op == MORPH_ERODE)
|
||||||
|
res = (trait.filterMinBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf));
|
||||||
|
else
|
||||||
|
res = (trait.filterMaxBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf));
|
||||||
|
}
|
||||||
|
return res >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // IPP_VERSION_X100 >= 810
|
#endif // IPP_VERSION_X100 >= 810
|
||||||
@ -1381,94 +1329,108 @@ 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;
|
Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
|
||||||
int iterations;
|
Point anchor(anchor_x, anchor_y);
|
||||||
int src_type;
|
Vec<double, 4> borderVal(borderValue);
|
||||||
int dst_type;
|
Ptr<FilterEngine> f = createMorphologyFilter(op, src_type, kernel, anchor, borderType, borderType, borderVal);
|
||||||
bool init(int op, int _src_type, int _dst_type, int, int,
|
Mat src(Size(width, height), src_type, src_data, src_step);
|
||||||
int kernel_type, uchar * kernel_data, size_t kernel_step, int kernel_width, int kernel_height,
|
Mat dst(Size(width, height), dst_type, dst_data, dst_step);
|
||||||
int anchor_x, int anchor_y,
|
|
||||||
int borderType, const double _borderValue[4],
|
|
||||||
int _iterations, bool, bool)
|
|
||||||
{
|
{
|
||||||
iterations = _iterations;
|
Point ofs(roi_x, roi_y);
|
||||||
src_type = _src_type;
|
Size wsz(roi_width, roi_height);
|
||||||
dst_type = _dst_type;
|
f->apply( src, dst, wsz, ofs );
|
||||||
Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
|
|
||||||
Point anchor(anchor_x, anchor_y);
|
|
||||||
Vec<double, 4> borderValue(_borderValue);
|
|
||||||
f = createMorphologyFilter(op, src_type, kernel, anchor, borderType, borderType, borderValue );
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
Point ofs(roi_x2, roi_y2);
|
||||||
|
Size wsz(roi_width2, roi_height2);
|
||||||
|
for( int i = 1; i < iterations; i++ )
|
||||||
|
f->apply( dst, dst, wsz, ofs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 dst(Size(width, height), dst_type, dst_data, dst_step);
|
|
||||||
{
|
|
||||||
Point ofs(roi_x, roi_y);
|
|
||||||
Size wsz(roi_width, roi_height);
|
|
||||||
f->apply( src, dst, wsz, ofs );
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Point ofs(roi_x2, roi_y2);
|
|
||||||
Size wsz(roi_width2, roi_height2);
|
|
||||||
for( int i = 1; i < iterations; i++ )
|
|
||||||
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,
|
|||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user