mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
ICV2017u3 package update;
- Optimizations set change. Now IPP integrations will provide code for SSE42, AVX2 and AVX512 (SKX) CPUs only. For HW below SSE42 IPP code is disabled. - Performance regressions fixes for IPP code paths; - cv::boxFilter integration improvement; - cv::filter2D integration improvement;
This commit is contained in:
@@ -95,7 +95,7 @@ static bool ipp_Canny(const Mat& src , const Mat& dx_, const Mat& dy_, Mat& dst,
|
||||
ippiGetImage(dy_, iwSrcDy);
|
||||
ippiGetImage(dst, iwDst);
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCannyDeriv, &iwSrcDx, &iwSrcDy, &iwDst, norm, low, high);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCannyDeriv, iwSrcDx, iwSrcDy, iwDst, low, high, ::ipp::IwiFilterCannyDerivParams(norm));
|
||||
}
|
||||
catch (::ipp::IwException ex)
|
||||
{
|
||||
@@ -121,7 +121,7 @@ static bool ipp_Canny(const Mat& src , const Mat& dx_, const Mat& dy_, Mat& dst,
|
||||
ippiGetImage(src, iwSrc);
|
||||
ippiGetImage(dst, iwDst);
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCanny, &iwSrc, &iwDst, ippFilterSobel, kernel, norm, low, high, ippBorderRepl);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCanny, iwSrc, iwDst, low, high, ::ipp::IwiFilterCannyParams(ippFilterSobel, kernel, norm), ippBorderRepl);
|
||||
}
|
||||
catch (::ipp::IwException)
|
||||
{
|
||||
|
||||
@@ -469,11 +469,32 @@ static ippiGeneralFunc ippiRGB2GrayC4Tab[] =
|
||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_AC4C1R, 0, 0
|
||||
};
|
||||
|
||||
static ippiGeneralFunc ippiCopyP3C3RTab[] =
|
||||
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
(ippiGeneralFunc)ippiCopy_8u_P3C3R, 0, (ippiGeneralFunc)ippiCopy_16u_P3C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiCopy_32f_P3C3R, 0, 0
|
||||
};
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize, Ipp8u aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize, Ipp16u aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize, Ipp32f aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
|
||||
#if !IPP_DISABLE_RGB_XYZ
|
||||
static ippiGeneralFunc ippiRGB2XYZTab[] =
|
||||
@@ -580,48 +601,31 @@ private:
|
||||
Ipp32f coeffs[3];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IPPGray2BGRFunctor
|
||||
{
|
||||
IPPGray2BGRFunctor(ippiGeneralFunc _func) :
|
||||
ippiGrayToBGR(_func)
|
||||
{
|
||||
}
|
||||
IPPGray2BGRFunctor(){}
|
||||
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
if (ippiGrayToBGR == 0)
|
||||
return false;
|
||||
|
||||
const void* srcarray[3] = { src, src, src };
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToBGR, srcarray, srcStep, dst, dstStep, ippiSize(cols, rows)) >= 0;
|
||||
return ippiGrayToRGB_C1C3R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows)) >= 0;
|
||||
}
|
||||
private:
|
||||
ippiGeneralFunc ippiGrayToBGR;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IPPGray2BGRAFunctor
|
||||
{
|
||||
IPPGray2BGRAFunctor(ippiGeneralFunc _func1, ippiReorderFunc _func2, int _depth) :
|
||||
ippiColorConvertGeneral(_func1), ippiColorConvertReorder(_func2), depth(_depth)
|
||||
IPPGray2BGRAFunctor()
|
||||
{
|
||||
alpha = ColorChannel<T>::max();
|
||||
}
|
||||
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
if (ippiColorConvertGeneral == 0 || ippiColorConvertReorder == 0)
|
||||
return false;
|
||||
|
||||
const void* srcarray[3] = { src, src, src };
|
||||
Mat temp(rows, cols, CV_MAKETYPE(depth, 3));
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, srcarray, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows)) < 0)
|
||||
return false;
|
||||
int order[4] = {0, 1, 2, 3};
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows), order) >= 0;
|
||||
return ippiGrayToRGB_C1C4R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows), alpha) >= 0;
|
||||
}
|
||||
private:
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
int depth;
|
||||
|
||||
T alpha;
|
||||
};
|
||||
|
||||
struct IPPReorderGeneralFunctor
|
||||
@@ -9744,18 +9748,27 @@ void cvtGraytoBGR(const uchar * src_data, size_t src_step,
|
||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
bool ippres = false;
|
||||
if(dcn == 3)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGray2BGRFunctor(ippiCopyP3C3RTab[depth])) )
|
||||
return;
|
||||
if( depth == CV_8U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp8u>());
|
||||
else if( depth == CV_16U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp16u>());
|
||||
else
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp32f>());
|
||||
}
|
||||
else if(dcn == 4)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGray2BGRAFunctor(ippiCopyP3C3RTab[depth], ippiSwapChannelsC3C4RTab[depth], depth)) )
|
||||
return;
|
||||
if( depth == CV_8U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp8u>());
|
||||
else if( depth == CV_16U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp16u>());
|
||||
else
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp32f>());
|
||||
}
|
||||
if(ippres)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -312,7 +312,7 @@ static bool ipp_Deriv(InputArray _src, OutputArray _dst, int dx, int dy, int ksi
|
||||
::ipp::IwiImage iwDstProc = iwDst;
|
||||
::ipp::IwiBorderSize borderSize(maskSize);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder.m_borderType)
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
if(srcType == ipp8u && dstType == ipp8u)
|
||||
@@ -324,17 +324,17 @@ static bool ipp_Deriv(InputArray _src, OutputArray _dst, int dx, int dy, int ksi
|
||||
{
|
||||
iwSrc -= borderSize;
|
||||
iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwSrcProc, 1, 0, ippAlgHintFast);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwSrcProc, 1, 0, ::ipp::IwiScaleParams(ippAlgHintFast));
|
||||
iwSrcProc += borderSize;
|
||||
}
|
||||
|
||||
if(useScharr)
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterScharr, &iwSrcProc, &iwDstProc, derivType, maskSize, ippBorder);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterScharr, iwSrcProc, iwDstProc, derivType, maskSize, ::ipp::IwDefault(), ippBorder);
|
||||
else
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterSobel, &iwSrcProc, &iwDstProc, derivType, maskSize, ippBorder);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterSobel, iwSrcProc, iwDstProc, derivType, maskSize, ::ipp::IwDefault(), ippBorder);
|
||||
|
||||
if(useScale)
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwDstProc, &iwDst, scale, delta, ippAlgHintFast);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwDstProc, iwDst, scale, delta, ::ipp::IwiScaleParams(ippAlgHintFast));
|
||||
}
|
||||
catch (::ipp::IwException)
|
||||
{
|
||||
@@ -732,7 +732,7 @@ static bool ipp_Laplacian(InputArray _src, OutputArray _dst, int ksize, double s
|
||||
::ipp::IwiImage iwDstProc = iwDst;
|
||||
::ipp::IwiBorderSize borderSize(maskSize);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder.m_borderType)
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
if(srcType == ipp8u && dstType == ipp8u)
|
||||
@@ -744,14 +744,14 @@ static bool ipp_Laplacian(InputArray _src, OutputArray _dst, int ksize, double s
|
||||
{
|
||||
iwSrc -= borderSize;
|
||||
iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwSrcProc, 1, 0);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwSrcProc, 1, 0);
|
||||
iwSrcProc += borderSize;
|
||||
}
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterLaplacian, &iwSrcProc, &iwDstProc, maskSize, ippBorder);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterLaplacian, iwSrcProc, iwDstProc, maskSize, ::ipp::IwDefault(), ippBorder);
|
||||
|
||||
if(useScale)
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwDstProc, &iwDst, scale, delta);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwDstProc, iwDst, scale, delta);
|
||||
|
||||
}
|
||||
catch (::ipp::IwException ex)
|
||||
|
||||
+77
-175
@@ -4560,170 +4560,88 @@ static bool replacementFilter2D(int stype, int dtype, int kernel_type,
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
typedef IppStatus(CV_STDCALL* IppiFilterBorder)(
|
||||
const void* pSrc, int srcStep, void* pDst, int dstStep,
|
||||
IppiSize dstRoiSize, IppiBorderType border, const void* borderValue,
|
||||
const IppiFilterBorderSpec* pSpec, Ipp8u* pBuffer);
|
||||
|
||||
static IppiFilterBorder getIppFunc(int stype)
|
||||
{
|
||||
switch (stype)
|
||||
{
|
||||
case CV_8UC1:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_8u_C1R);
|
||||
case CV_8UC3:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_8u_C3R);
|
||||
case CV_8UC4:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_8u_C4R);
|
||||
case CV_16UC1:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_16u_C1R);
|
||||
case CV_16UC3:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_16u_C3R);
|
||||
case CV_16UC4:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_16u_C4R);
|
||||
case CV_16SC1:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_16s_C1R);
|
||||
case CV_16SC3:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_16s_C3R);
|
||||
case CV_16SC4:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_16s_C4R);
|
||||
case CV_32FC1:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_32f_C1R);
|
||||
case CV_32FC3:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_32f_C3R);
|
||||
case CV_32FC4:
|
||||
return reinterpret_cast<IppiFilterBorder>(ippiFilterBorder_32f_C4R);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <int kdepth>
|
||||
struct IppFilterTrait { };
|
||||
|
||||
template <>
|
||||
struct IppFilterTrait<CV_16S>
|
||||
{
|
||||
enum { kernel_type_id = CV_16SC1 };
|
||||
typedef Ipp16s kernel_type;
|
||||
typedef IppStatus(CV_STDCALL* copy_fun_type)(const kernel_type* pSrc, int srcStep, kernel_type* pDst, int dstStep, IppiSize roiSize);
|
||||
inline static copy_fun_type get_copy_fun() { return ippiCopy_16s_C1R; }
|
||||
inline static IppStatus runInit(const kernel_type* pKernel, IppiSize kernelSize, int divisor, IppDataType dataType, int numChannels, IppRoundMode roundMode, IppiFilterBorderSpec* pSpec)
|
||||
{
|
||||
return ippiFilterBorderInit_16s(pKernel, kernelSize, divisor, dataType, numChannels, roundMode, pSpec);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IppFilterTrait<CV_32F>
|
||||
{
|
||||
enum { kernel_type_id = CV_32FC1 };
|
||||
typedef Ipp32f kernel_type;
|
||||
typedef IppStatus(CV_STDCALL* copy_fun_type)(const kernel_type* pSrc, int srcStep, kernel_type* pDst, int dstStep, IppiSize roiSize);
|
||||
inline static copy_fun_type get_copy_fun() { return ippiCopy_32f_C1R; }
|
||||
inline static IppStatus runInit(const kernel_type* pKernel, IppiSize kernelSize, int divisor, IppDataType dataType, int numChannels, IppRoundMode roundMode, IppiFilterBorderSpec* pSpec)
|
||||
{
|
||||
CV_UNUSED(divisor);
|
||||
return ippiFilterBorderInit_32f(pKernel, kernelSize, dataType, numChannels, roundMode, pSpec);
|
||||
}
|
||||
};
|
||||
|
||||
template <int kdepth>
|
||||
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)
|
||||
static bool ippFilter2D(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)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
typedef IppFilterTrait<kdepth> trait;
|
||||
typedef typename trait::kernel_type kernel_type;
|
||||
::ipp::IwiSize iwSize(width, height);
|
||||
::ipp::IwiSize kernelSize(kernel_width, kernel_height);
|
||||
IppDataType type = ippiGetDataType(CV_MAT_DEPTH(stype));
|
||||
int channels = CV_MAT_CN(stype);
|
||||
|
||||
IppAutoBuffer<IppiFilterBorderSpec> spec;
|
||||
IppAutoBuffer<Ipp8u> buffer;
|
||||
IppAutoBuffer<kernel_type> kernelBuffer;
|
||||
IppiBorderType ippBorderType;
|
||||
int src_type;
|
||||
|
||||
Point anchor(anchor_x, anchor_y);
|
||||
#if IPP_VERSION_X100 >= 900
|
||||
Point ippAnchor((kernel_width - 1) / 2, (kernel_height - 1) / 2);
|
||||
#else
|
||||
Point ippAnchor(kernel_width >> 1, kernel_height >> 1);
|
||||
#endif
|
||||
bool isIsolated = (borderType & BORDER_ISOLATED) != 0;
|
||||
int borderTypeNI = borderType & ~BORDER_ISOLATED;
|
||||
ippBorderType = ippiGetBorderType(borderTypeNI);
|
||||
int ddepth = CV_MAT_DEPTH(dtype);
|
||||
int sdepth = CV_MAT_DEPTH(stype);
|
||||
CV_UNUSED(isSubmatrix);
|
||||
|
||||
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 <= 201702 // IPP bug with 1x1 kernel
|
||||
if(kernel_width == 1 && kernel_height == 1)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
bool runIpp = true
|
||||
&& (borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE)
|
||||
&& (sdepth == ddepth)
|
||||
&& (getIppFunc(stype))
|
||||
&& ((int)ippBorderType > 0)
|
||||
&& (!isSubmatrix || isIsolated)
|
||||
&& (std::fabs(delta - 0) < DBL_EPSILON)
|
||||
&& (ippAnchor == anchor)
|
||||
&& src_data != dst_data;
|
||||
|
||||
if (!runIpp)
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Too big difference compared to OpenCV FFT-based convolution
|
||||
if(kernel_type == CV_32FC1 && (type == ipp16s || type == ipp16u) && (kernel_width > 7 || kernel_height > 7))
|
||||
return false;
|
||||
|
||||
src_type = stype;
|
||||
int cn = CV_MAT_CN(stype);
|
||||
IppiSize kernelSize = { kernel_width, kernel_height };
|
||||
IppDataType dataType = ippiGetDataType(ddepth);
|
||||
IppDataType kernelType = ippiGetDataType(kdepth);
|
||||
Ipp32s specSize = 0;
|
||||
Ipp32s bufsize = 0;
|
||||
IppiSize dstRoiSize = { width, height };
|
||||
IppStatus status;
|
||||
|
||||
status = ippiFilterBorderGetSize(kernelSize, dstRoiSize, dataType, kernelType, cn, &specSize, &bufsize);
|
||||
if (status < 0)
|
||||
// Poor optimization for big kernels
|
||||
if(kernel_width > 7 || kernel_height > 7)
|
||||
return false;
|
||||
|
||||
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 (kernel_step != good_kernel_step) {
|
||||
kernelBuffer.allocate((int)good_kernel_step * kernelSize.height);
|
||||
status = trait::get_copy_fun()((kernel_type*)kernel_data, (int)kernel_step, kernelBuffer, (int)good_kernel_step, kernelSize);
|
||||
if (status < 0)
|
||||
return false;
|
||||
pKerBuffer = kernelBuffer;
|
||||
}
|
||||
#else
|
||||
kernelBuffer.Alloc(good_kernel_step * kernelSize.height);
|
||||
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);
|
||||
flip(kernel, kerFlip, -1);
|
||||
pKerBuffer = kernelBuffer;
|
||||
#endif
|
||||
spec.allocate(specSize);
|
||||
buffer.allocate(bufsize);
|
||||
status = trait::runInit(pKerBuffer, kernelSize, 0, dataType, cn, ippRndFinancial, spec);
|
||||
if (status < 0) {
|
||||
|
||||
if(src_data == dst_data)
|
||||
return false;
|
||||
|
||||
if(stype != dtype)
|
||||
return false;
|
||||
|
||||
if(kernel_type != CV_16SC1 && kernel_type != CV_32FC1)
|
||||
return false;
|
||||
|
||||
// TODO: Implement offset for 8u, 16u
|
||||
if(std::fabs(delta) >= DBL_EPSILON)
|
||||
return false;
|
||||
|
||||
if(!ippiCheckAnchor(anchor_x, anchor_y, kernel_width, kernel_height))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiBorderSize iwBorderSize;
|
||||
::ipp::IwiBorderType iwBorderType;
|
||||
::ipp::IwiImage iwKernel(ippiSize(kernel_width, kernel_height), ippiGetDataType(CV_MAT_DEPTH(kernel_type)), CV_MAT_CN(kernel_type), 0, (void*)kernel_data, kernel_step);
|
||||
::ipp::IwiImage iwSrc(iwSize, type, channels, ::ipp::IwiBorderSize(offset_x, offset_y, full_width-offset_x-width, full_height-offset_y-height), (void*)src_data, src_step);
|
||||
::ipp::IwiImage iwDst(iwSize, type, channels, ::ipp::IwiBorderSize(offset_x, offset_y, full_width-offset_x-width, full_height-offset_y-height), (void*)dst_data, dst_step);
|
||||
|
||||
iwBorderSize = ::ipp::iwiSizeToBorderSize(kernelSize);
|
||||
iwBorderType = ippiGetBorder(iwSrc, borderType, iwBorderSize);
|
||||
if(!iwBorderType)
|
||||
return false;
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilter, iwSrc, iwDst, iwKernel, ::ipp::IwiFilterParams(1, 0, ippAlgHintNone, ippRndFinancial), iwBorderType);
|
||||
}
|
||||
catch(::ipp::IwException ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IppiFilterBorder ippiFilterBorder = getIppFunc(src_type);
|
||||
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);
|
||||
if (status >= 0) {
|
||||
CV_IMPL_ADD(CV_IMPL_IPP);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(stype); CV_UNUSED(dtype); CV_UNUSED(kernel_type); CV_UNUSED(src_data); CV_UNUSED(src_step);
|
||||
CV_UNUSED(dst_data); CV_UNUSED(dst_step); CV_UNUSED(width); CV_UNUSED(height); CV_UNUSED(full_width);
|
||||
CV_UNUSED(full_height); CV_UNUSED(offset_x); CV_UNUSED(offset_y); CV_UNUSED(kernel_data); CV_UNUSED(kernel_step);
|
||||
CV_UNUSED(kernel_width); CV_UNUSED(kernel_height); CV_UNUSED(anchor_x); CV_UNUSED(anchor_y); CV_UNUSED(delta);
|
||||
CV_UNUSED(borderType); CV_UNUSED(isSubmatrix);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4902,34 +4820,18 @@ void filter2D(int stype, int dtype, int kernel_type,
|
||||
delta, borderType, isSubmatrix);
|
||||
if (res)
|
||||
return;
|
||||
#ifdef HAVE_IPP
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
res = false;
|
||||
if (kernel_type == CV_32FC1) {
|
||||
res = ippFilter2D<CV_32F>(stype, dtype,
|
||||
src_data, src_step,
|
||||
dst_data, dst_step,
|
||||
width, height,
|
||||
kernel_data, kernel_step,
|
||||
kernel_width, kernel_height,
|
||||
anchor_x, anchor_y,
|
||||
delta, borderType, isSubmatrix);
|
||||
}
|
||||
else if (kernel_type == CV_16SC1) {
|
||||
res = ippFilter2D<CV_16S>(stype, dtype,
|
||||
src_data, src_step,
|
||||
dst_data, dst_step,
|
||||
width, height,
|
||||
kernel_data, kernel_step,
|
||||
kernel_width, kernel_height,
|
||||
anchor_x, anchor_y,
|
||||
delta, borderType, isSubmatrix);
|
||||
}
|
||||
if (res)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CV_IPP_RUN_FAST(ippFilter2D(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))
|
||||
|
||||
res = dftFilter2D(stype, dtype, kernel_type,
|
||||
src_data, src_step,
|
||||
dst_data, dst_step,
|
||||
|
||||
@@ -370,6 +370,18 @@ void crossCorr( const Mat& src, const Mat& templ, Mat& dst,
|
||||
Point anchor=Point(0,0), double delta=0,
|
||||
int borderType=BORDER_REFLECT_101 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
static inline bool ippiCheckAnchor(cv::Point anchor, cv::Size ksize)
|
||||
{
|
||||
anchor = cv::normalizeAnchor(anchor, ksize);
|
||||
if(anchor.x != ((ksize.width-1)/2) || anchor.y != ((ksize.height-1)/2))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1194,10 +1194,8 @@ static IppiHistogram_C1 getIppiHistogramFunction_C1(int type)
|
||||
{
|
||||
IppiHistogram_C1 ippFunction =
|
||||
(type == CV_8UC1) ? (IppiHistogram_C1)ippiHistogram_8u_C1R :
|
||||
#if IPP_VERSION_X100 >= 201700 || !(defined HAVE_IPP_ICV_ONLY)
|
||||
(type == CV_16UC1) ? (IppiHistogram_C1)ippiHistogram_16u_C1R :
|
||||
(type == CV_32FC1) ? (IppiHistogram_C1)ippiHistogram_32f_C1R :
|
||||
#endif
|
||||
NULL;
|
||||
|
||||
return ippFunction;
|
||||
@@ -1401,9 +1399,9 @@ static bool ipp_calchist(const Mat &image, Mat &hist, int histSize, const float*
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// No SSE42 optimization for uniform 32f
|
||||
#if IPP_DISABLE_PERF_HISTU32F_SSE42
|
||||
if(uniform && image.depth() == CV_32F && !(ipp::getIppFeatures()&ippCPUID_AVX))
|
||||
if(uniform && image.depth() == CV_32F && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2971,8 +2971,8 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(iwiResize, &m_src, &m_dst, &roi);
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(iwiResize, m_src, m_dst, ippBorderRepl, tile);
|
||||
}
|
||||
catch(::ipp::IwException)
|
||||
{
|
||||
@@ -3007,7 +3007,7 @@ public:
|
||||
{0, scaleY, shift+0.5*scaleY}
|
||||
};
|
||||
|
||||
iwiWarpAffine.InitAlloc(m_src.m_size, m_dst.m_size, m_src.m_dataType, m_src.m_channels, coeffs, ippWarpForward, inter, ::ipp::IwiWarpAffineParams(0, 0.75, 0), ippBorderRepl);
|
||||
iwiWarpAffine.InitAlloc(m_src.m_size, m_dst.m_size, m_src.m_dataType, m_src.m_channels, coeffs, iwTransForward, inter, ::ipp::IwiWarpAffineParams(0, 0, 0.75), ippBorderRepl);
|
||||
|
||||
m_ok = true;
|
||||
}
|
||||
@@ -3021,8 +3021,8 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(iwiWarpAffine, &m_src, &m_dst, &roi);
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(iwiWarpAffine, m_src, m_dst, tile);
|
||||
}
|
||||
catch(::ipp::IwException)
|
||||
{
|
||||
@@ -3053,23 +3053,28 @@ static bool ipp_resize(const uchar * src_data, size_t src_step, int src_width, i
|
||||
if(ippInter < 0)
|
||||
return false;
|
||||
|
||||
#if IPP_DISABLE_RESIZE_NEAREST
|
||||
if(ippInter == ippNearest)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if IPP_DISABLE_RESIZE_AREA
|
||||
if(ippInter == ippSuper)
|
||||
return false;
|
||||
#endif
|
||||
// Resize which doesn't match OpenCV exactly
|
||||
if(!cv::ipp::useIPP_NE())
|
||||
{
|
||||
if(ippInter == ippNearest || ippInter == ippSuper || (ippDataType == ipp8u && ippInter == ippLinear))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ippInter != ippLinear && ippDataType == ipp64f)
|
||||
return false;
|
||||
|
||||
// Accuracy mismatch is 1 but affects detectors greatly
|
||||
#if IPP_DISABLE_RESIZE_8U
|
||||
if(ippDataType == ipp8u && ippInter == ippLinear)
|
||||
return false;
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Degradations on int^2 linear downscale
|
||||
if(ippDataType != ipp64f && ippInter == ippLinear && inv_scale_x < 1 && inv_scale_y < 1) // if downscale
|
||||
{
|
||||
int scale_x = (int)(1/inv_scale_x);
|
||||
int scale_y = (int)(1/inv_scale_y);
|
||||
if(1/inv_scale_x - scale_x < DBL_EPSILON && 1/inv_scale_y - scale_y < DBL_EPSILON) // if integer
|
||||
{
|
||||
if(!(scale_x&(scale_x-1)) && !(scale_y&(scale_y-1))) // if power of 2
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool affine = false;
|
||||
|
||||
@@ -571,6 +571,12 @@ static bool ipp_moments(Mat &src, Moments &m )
|
||||
#if IPP_VERSION_X100 >= 900
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Degradations for CV_8UC1
|
||||
if(src.type() == CV_8UC1)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
IppiSize roi = { src.cols, src.rows };
|
||||
IppiPoint point = { 0, 0 };
|
||||
int type = src.type();
|
||||
|
||||
@@ -1140,20 +1140,41 @@ static bool ippMorph(int op, int src_type, int dst_type,
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
// Problem with SSE42 optimizations
|
||||
#if IPP_DISABLE_PERF_MORPH_SSE42
|
||||
if(!(ipp::getIppFeatures()&ippCPUID_AVX))
|
||||
#if IPP_VERSION_X100 < 201800
|
||||
// Problem with SSE42 optimizations performance
|
||||
if(cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
return false;
|
||||
|
||||
// Different mask flipping
|
||||
if(op == MORPH_GRADIENT)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
::ipp::IwAutoBuffer<Ipp8u> kernelTempBuffer;
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Problem with AVX512 optimizations performance
|
||||
if(cv::ipp::getIppTopFeatures()&ippCPUID_AVX512F)
|
||||
return false;
|
||||
|
||||
// Multiple iterations on small mask is not effective in current integration
|
||||
// Implace imitation for 3x3 kernel is not efficient
|
||||
// Advanced morphology for small mask introduces degradations
|
||||
if((iterations > 1 || src_data == dst_data || (op != MORPH_ERODE && op != MORPH_DILATE)) && kernel_width*kernel_height < 25)
|
||||
return false;
|
||||
|
||||
// Skip even mask sizes for advanced morphology since they can produce out of spec writes
|
||||
if((op != MORPH_ERODE && op != MORPH_DILATE) && (!(kernel_width&1) || !(kernel_height&1)))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
IppAutoBuffer<Ipp8u> kernelTempBuffer;
|
||||
::ipp::IwiBorderSize iwBorderSize;
|
||||
::ipp::IwiBorderSize iwBorderSize2;
|
||||
::ipp::IwiBorderType iwBorderType;
|
||||
::ipp::IwiBorderType iwBorderType2;
|
||||
::ipp::IwiImage iwMask;
|
||||
::ipp::IwiImage iwInter;
|
||||
::ipp::IwiSize initSize(width, height);
|
||||
::ipp::IwiSize kernelSize(kernel_width, kernel_height);
|
||||
::ipp::IwiPoint anchor(anchor_x, anchor_y);
|
||||
IppDataType type = ippiGetDataType(CV_MAT_DEPTH(src_type));
|
||||
int channels = CV_MAT_CN(src_type);
|
||||
IwiMorphologyType morphType = ippiGetMorphologyType(op);
|
||||
@@ -1169,68 +1190,99 @@ static bool ippMorph(int op, int src_type, int dst_type,
|
||||
if(src_type != dst_type)
|
||||
return false;
|
||||
|
||||
if(!ippiCheckAnchor(anchor_x, anchor_y, kernel_width, kernel_height))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiImage iwSrc(initSize, type, channels, ::ipp::IwiBorderSize(roi_x, roi_y, roi_width-roi_x-width, roi_height-roi_y-height), (void*)src_data, src_step);
|
||||
::ipp::IwiImage iwDst(initSize, type, channels, ::ipp::IwiBorderSize(roi_x2, roi_y2, roi_width2-roi_x2-width, roi_height2-roi_y2-height), (void*)dst_data, dst_step);
|
||||
|
||||
::ipp::iwiFilterMorphology_GetBorderSize(morphType, kernelSize, iwBorderSize);
|
||||
if(morphType != iwiMorphErode && morphType != iwiMorphDilate)
|
||||
iwBorderSize = ::ipp::iwiSizeToBorderSize(kernelSize);
|
||||
iwBorderType = ippiGetBorder(iwSrc, borderType, iwBorderSize);
|
||||
if(!iwBorderType)
|
||||
return false;
|
||||
if(iterations > 1)
|
||||
{
|
||||
iwBorderSize.borderLeft /= 2;
|
||||
iwBorderSize.borderTop /= 2;
|
||||
iwBorderSize.borderRight /= 2;
|
||||
iwBorderSize.borderBottom /= 2;
|
||||
// Check dst border for second and later iterations
|
||||
iwBorderSize2 = ::ipp::iwiSizeToBorderSize(kernelSize);
|
||||
iwBorderType2 = ippiGetBorder(iwDst, borderType, iwBorderSize2);
|
||||
if(!iwBorderType2)
|
||||
return false;
|
||||
}
|
||||
|
||||
iwBorderType = ippiGetBorder(iwSrc, borderType, iwBorderSize);
|
||||
if(!iwBorderType.m_borderType || ((iwBorderType.m_borderFlags&ippBorderInMem) && (iwBorderType.m_borderFlags&ippBorderInMem) != ippBorderInMem))
|
||||
return false;
|
||||
if(morphType != iwiMorphErode && morphType != iwiMorphDilate && morphType != iwiMorphGradient)
|
||||
{
|
||||
// For now complex morphology support only InMem around all sides. This will be improved later.
|
||||
if((iwBorderType&ippBorderInMem) && (iwBorderType&ippBorderInMem) != ippBorderInMem)
|
||||
return false;
|
||||
|
||||
if(iwBorderType.m_borderType == ippBorderConst)
|
||||
if((iwBorderType&ippBorderInMem) == ippBorderInMem)
|
||||
{
|
||||
iwBorderType &= ~ippBorderInMem;
|
||||
iwBorderType &= ippBorderFirstStageInMem;
|
||||
}
|
||||
}
|
||||
|
||||
if(iwBorderType.StripFlags() == ippBorderConst)
|
||||
{
|
||||
if(Vec<double, 4>(borderValue) == morphologyDefaultBorderValue())
|
||||
iwBorderType.m_borderType = ippBorderDefault;
|
||||
iwBorderType.SetType(ippBorderDefault);
|
||||
else
|
||||
iwBorderType.SetValue(borderValue[0], borderValue[1], borderValue[2], borderValue[3]);
|
||||
}
|
||||
if(morphType != iwiMorphErode && morphType != iwiMorphDilate)
|
||||
{
|
||||
if((iwBorderType.m_borderFlags&ippBorderInMem) == ippBorderInMem)
|
||||
iwBorderType.m_borderFlags = ippBorderFirstStageInMem;
|
||||
}
|
||||
|
||||
// Test input parameters on dummy structures
|
||||
{
|
||||
::ipp::IwiImage testSrc(initSize, type, channels);
|
||||
::ipp::IwiImage testDst(initSize, type, channels);
|
||||
::ipp::IwiImage testMask(ippiSize(kernel_width, kernel_height), ipp8u, CV_MAT_CN(kernel_type));
|
||||
|
||||
::ipp::iwiFilterMorphology(&testSrc, &testDst, morphType, &testMask, &anchor, iwBorderType);
|
||||
iwBorderType.m_value = ::ipp::IwValueFloat(borderValue[0], borderValue[1], borderValue[2], borderValue[3]);
|
||||
}
|
||||
|
||||
iwMask.Init(ippiSize(kernel_width, kernel_height), ippiGetDataType(CV_MAT_DEPTH(kernel_type)), CV_MAT_CN(kernel_type), 0, kernel_data, kernel_step);
|
||||
if((int)kernel_step != kernel_width || CV_MAT_DEPTH(kernel_type) != CV_8U)
|
||||
|
||||
::ipp::IwiImage iwMaskLoc = iwMask;
|
||||
if(morphType == iwiMorphDilate)
|
||||
{
|
||||
kernelTempBuffer.Alloc(kernel_width*kernel_height);
|
||||
::ipp::IwiImage iwMaskTmp(ippiSize(kernel_width, kernel_height), ipp8u, 1, 0, kernelTempBuffer, kernel_width);
|
||||
::ipp::iwiScale(&iwMask, &iwMaskTmp, 1, 0);
|
||||
iwMask = iwMaskTmp;
|
||||
iwMaskLoc.Alloc(iwMask.m_size, iwMask.m_dataType, iwMask.m_channels);
|
||||
::ipp::iwiMirror(iwMask, iwMaskLoc, ippAxsBoth);
|
||||
iwMask = iwMaskLoc;
|
||||
}
|
||||
|
||||
if(iterations > 1)
|
||||
{
|
||||
iwInter.Alloc(initSize, type, channels);
|
||||
// OpenCV uses in mem border from dst for two and more iterations, so we need to keep this border in intermediate image
|
||||
iwInter.Alloc(initSize, type, channels, iwBorderSize2);
|
||||
|
||||
::ipp::IwiImage *pSwap[2] = {&iwInter, &iwDst};
|
||||
::ipp::IwiBorderType iterBorder = iwBorderType;
|
||||
iterBorder.m_borderFlags = 0;
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, &iwSrc, &iwInter, morphType, &iwMask, NULL, iwBorderType);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, iwSrc, iwInter, morphType, iwMask, ::ipp::IwDefault(), iwBorderType);
|
||||
|
||||
// Copy border only
|
||||
{
|
||||
if(iwBorderSize2.top)
|
||||
{
|
||||
::ipp::IwiRoi borderRoi(-iwBorderSize2.left, -iwBorderSize2.top, iwDst.m_size.width+iwBorderSize2.left+iwBorderSize2.right, iwBorderSize2.top);
|
||||
::ipp::IwiImage iwInterRoi = iwInter.GetRoiImage(borderRoi);
|
||||
::ipp::iwiCopy(iwDst.GetRoiImage(borderRoi), iwInterRoi);
|
||||
}
|
||||
if(iwBorderSize2.bottom)
|
||||
{
|
||||
::ipp::IwiRoi borderRoi(-iwBorderSize2.left, iwDst.m_size.height, iwDst.m_size.width+iwBorderSize2.left+iwBorderSize2.right, iwBorderSize2.bottom);
|
||||
::ipp::IwiImage iwInterRoi = iwInter.GetRoiImage(borderRoi);
|
||||
::ipp::iwiCopy(iwDst.GetRoiImage(borderRoi), iwInterRoi);
|
||||
}
|
||||
if(iwBorderSize2.left)
|
||||
{
|
||||
::ipp::IwiRoi borderRoi(-iwBorderSize2.left, 0, iwBorderSize2.left, iwDst.m_size.height);
|
||||
::ipp::IwiImage iwInterRoi = iwInter.GetRoiImage(borderRoi);
|
||||
::ipp::iwiCopy(iwDst.GetRoiImage(borderRoi), iwInterRoi);
|
||||
}
|
||||
if(iwBorderSize2.right)
|
||||
{
|
||||
::ipp::IwiRoi borderRoi(iwDst.m_size.width, 0, iwBorderSize2.left, iwDst.m_size.height);
|
||||
::ipp::IwiImage iwInterRoi = iwInter.GetRoiImage(borderRoi);
|
||||
::ipp::iwiCopy(iwDst.GetRoiImage(borderRoi), iwInterRoi);
|
||||
}
|
||||
}
|
||||
|
||||
iwBorderType2.SetType(iwBorderType);
|
||||
for(int i = 0; i < iterations-1; i++)
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, pSwap[i&0x1], pSwap[(i+1)&0x1], morphType, &iwMask, NULL, iterBorder);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, *pSwap[i&0x1], *pSwap[(i+1)&0x1], morphType, iwMask, ::ipp::IwDefault(), iwBorderType2);
|
||||
if(iterations&0x1)
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiCopyMask, &iwInter, &iwDst);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiCopy, iwInter, iwDst);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1238,11 +1290,11 @@ static bool ippMorph(int op, int src_type, int dst_type,
|
||||
{
|
||||
iwInter.Alloc(initSize, type, channels);
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, &iwSrc, &iwInter, morphType, &iwMask, NULL, iwBorderType);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiCopyMask, &iwInter, &iwDst);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, iwSrc, iwInter, morphType, iwMask, ::ipp::IwDefault(), iwBorderType);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiCopy, iwInter, iwDst);
|
||||
}
|
||||
else
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, &iwSrc, &iwDst, morphType, &iwMask, NULL, iwBorderType);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, iwSrc, iwDst, morphType, iwMask, ::ipp::IwDefault(), iwBorderType);
|
||||
}
|
||||
}
|
||||
catch(::ipp::IwException ex)
|
||||
@@ -1912,6 +1964,7 @@ static bool ocl_morphologyEx(InputArray _src, OutputArray _dst, int op,
|
||||
}
|
||||
#endif
|
||||
|
||||
#define IPP_DISABLE_MORPH_ADV 1
|
||||
#ifdef HAVE_IPP
|
||||
#if !IPP_DISABLE_MORPH_ADV
|
||||
namespace cv {
|
||||
|
||||
@@ -1729,80 +1729,47 @@ namespace cv
|
||||
{
|
||||
static bool ipp_boxfilter(Mat &src, Mat &dst, Size ksize, Point anchor, bool normalize, int borderType)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
// Problem with SSE42 optimization for 16s
|
||||
#if IPP_DISABLE_PERF_BOX16S_SSE42
|
||||
if(src.depth() == CV_16S && !(ipp::getIppFeatures()&ippCPUID_AVX))
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Problem with SSE42 optimization for 16s and some 8u modes
|
||||
if(ipp::getIppTopFeatures() == ippCPUID_SSE42 && (((src.depth() == CV_16S || src.depth() == CV_16U) && (src.channels() == 3 || src.channels() == 4)) || (src.depth() == CV_8U && src.channels() == 3 && (ksize.width > 5 || ksize.height > 5))))
|
||||
return false;
|
||||
|
||||
// Other optimizations has some degradations too
|
||||
if((((src.depth() == CV_16S || src.depth() == CV_16U) && (src.channels() == 4)) || (src.depth() == CV_8U && src.channels() == 1 && (ksize.width > 5 || ksize.height > 5))))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
int stype = src.type(), cn = CV_MAT_CN(stype);
|
||||
IppiBorderType ippBorderType = ippiGetBorderType(borderType & ~BORDER_ISOLATED);
|
||||
IppDataType ippType = ippiGetDataType(stype);
|
||||
Point ocvAnchor, ippAnchor;
|
||||
ocvAnchor.x = anchor.x < 0 ? ksize.width / 2 : anchor.x;
|
||||
ocvAnchor.y = anchor.y < 0 ? ksize.height / 2 : anchor.y;
|
||||
ippAnchor.x = ksize.width / 2 - (ksize.width % 2 == 0 ? 1 : 0);
|
||||
ippAnchor.y = ksize.height / 2 - (ksize.height % 2 == 0 ? 1 : 0);
|
||||
if(!normalize)
|
||||
return false;
|
||||
|
||||
if(normalize && (!src.isSubmatrix() || borderType&BORDER_ISOLATED) && stype == dst.type() &&
|
||||
(ippBorderType == ippBorderRepl || /* returns ippStsStepErr: Step value is not valid */
|
||||
ippBorderType == ippBorderConst ||
|
||||
ippBorderType == ippBorderMirror) && ocvAnchor == ippAnchor) // returns ippStsMaskSizeErr: mask has an illegal value
|
||||
if(!ippiCheckAnchor(anchor, ksize))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
IppStatus status;
|
||||
Ipp32s bufSize = 0;
|
||||
IppiSize roiSize = { dst.cols, dst.rows };
|
||||
IppiSize maskSize = { ksize.width, ksize.height };
|
||||
IppAutoBuffer<Ipp8u> buffer;
|
||||
|
||||
if(ippiFilterBoxBorderGetBufferSize(roiSize, maskSize, ippType, cn, &bufSize) < 0)
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiSize iwKSize = ippiGetSize(ksize);
|
||||
::ipp::IwiBorderSize borderSize(iwKSize);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
buffer.allocate(bufSize);
|
||||
|
||||
#define IPP_FILTER_BOX_BORDER(ippType, flavor)\
|
||||
{\
|
||||
ippType borderValue[4] = { 0, 0, 0, 0 };\
|
||||
status = CV_INSTRUMENT_FUN_IPP(ippiFilterBoxBorder_##flavor, src.ptr<ippType>(), (int)src.step, dst.ptr<ippType>(),\
|
||||
(int)dst.step, roiSize, maskSize,\
|
||||
ippBorderType, borderValue, buffer);\
|
||||
}
|
||||
|
||||
if (stype == CV_8UC1)
|
||||
IPP_FILTER_BOX_BORDER(Ipp8u, 8u_C1R)
|
||||
else if (stype == CV_8UC3)
|
||||
IPP_FILTER_BOX_BORDER(Ipp8u, 8u_C3R)
|
||||
else if (stype == CV_8UC4)
|
||||
IPP_FILTER_BOX_BORDER(Ipp8u, 8u_C4R)
|
||||
else if (stype == CV_16UC1)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16u, 16u_C1R)
|
||||
else if (stype == CV_16UC3)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16u, 16u_C3R)
|
||||
else if (stype == CV_16UC4)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16u, 16u_C4R)
|
||||
else if (stype == CV_16SC1)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16s, 16s_C1R)
|
||||
else if (stype == CV_16SC3)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16s, 16s_C3R)
|
||||
else if (stype == CV_16SC4)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16s, 16s_C4R)
|
||||
else if (stype == CV_32FC1)
|
||||
IPP_FILTER_BOX_BORDER(Ipp32f, 32f_C1R)
|
||||
else if (stype == CV_32FC3)
|
||||
IPP_FILTER_BOX_BORDER(Ipp32f, 32f_C3R)
|
||||
else if (stype == CV_32FC4)
|
||||
IPP_FILTER_BOX_BORDER(Ipp32f, 32f_C4R)
|
||||
else
|
||||
return false;
|
||||
|
||||
if(status >= 0)
|
||||
return true;
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBox, iwSrc, iwDst, iwKSize, ::ipp::IwDefault(), ippBorder);
|
||||
}
|
||||
catch (::ipp::IwException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#undef IPP_FILTER_BOX_BORDER
|
||||
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(ksize); CV_UNUSED(anchor); CV_UNUSED(normalize); CV_UNUSED(borderType);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2241,8 +2208,11 @@ static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#define IPP_DISABLE_FILTERING_INMEM_PARTIAL 1 // IW 2017u2 has bug which doesn't allow use of partial inMem with tiling
|
||||
#if IPP_VERSION_X100 == 201702 // IW 2017u2 has bug which doesn't allow use of partial inMem with tiling
|
||||
#define IPP_GAUSSIANBLUR_PARALLEL 0
|
||||
#else
|
||||
#define IPP_GAUSSIANBLUR_PARALLEL 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
|
||||
@@ -2266,8 +2236,8 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &m_src, &m_dst, m_kernelSize, m_sigma, m_border, &roi);
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, m_dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, m_src, m_dst, m_kernelSize, m_sigma, ::ipp::IwDefault(), m_border, tile);
|
||||
}
|
||||
catch(::ipp::IwException e)
|
||||
{
|
||||
@@ -2295,7 +2265,7 @@ static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_VERSION_X100 <= 201702 && ((defined _MSC_VER && defined _M_IX86) || (defined __GNUC__ && defined __i386__))
|
||||
#if IPP_VERSION_X100 < 201800 && ((defined _MSC_VER && defined _M_IX86) || (defined __GNUC__ && defined __i386__))
|
||||
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ksize); CV_UNUSED(sigma1); CV_UNUSED(sigma2); CV_UNUSED(borderType);
|
||||
return false; // bug on ia32
|
||||
#else
|
||||
@@ -2313,17 +2283,15 @@ static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
|
||||
{
|
||||
Mat src = _src.getMat();
|
||||
Mat dst = _dst.getMat();
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiBorderSize borderSize(::ipp::IwiSize(ippiSize(ksize)));
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiBorderSize borderSize = ::ipp::iwiSizeToBorderSize(ippiGetSize(ksize));
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder.m_borderType)
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
const bool disableThreading = IPP_DISABLE_FILTERING_INMEM_PARTIAL &&
|
||||
((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem;
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
if(!disableThreading && IPP_GAUSSIANBLUR_PARALLEL && threads > 1) {
|
||||
if(IPP_GAUSSIANBLUR_PARALLEL && threads > 1) {
|
||||
bool ok;
|
||||
ipp_gaussianBlurParallel invoker(iwSrc, iwDst, ksize.width, (float) sigma1, ippBorder, &ok);
|
||||
|
||||
@@ -2335,7 +2303,7 @@ static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
|
||||
if(!ok)
|
||||
return false;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &iwSrc, &iwDst, ksize.width, (float) sigma1, ippBorder);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, iwSrc, iwDst, ksize.width, sigma1, ::ipp::IwDefault(), ippBorder);
|
||||
}
|
||||
}
|
||||
catch (::ipp::IwException ex)
|
||||
@@ -3411,6 +3379,12 @@ static bool ipp_medianFilter(Mat &src0, Mat &dst, int ksize)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Degradations for big kernel
|
||||
if(ksize > 7)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
{
|
||||
int bufSize;
|
||||
IppiSize dstRoiSize = ippiSize(dst.cols, dst.rows), maskSize = ippiSize(ksize, ksize);
|
||||
@@ -4279,8 +4253,8 @@ public:
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, &src, &dst, radius, valSquareSigma, posSquareSigma, ippiFilterBilateralGauss, ippDistNormL1, borderType, &roi);
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, src, dst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), borderType, tile);
|
||||
}
|
||||
catch(::ipp::IwException)
|
||||
{
|
||||
@@ -4318,13 +4292,11 @@ static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, do
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiBorderSize borderSize(radius);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder.m_borderType)
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
const bool disableThreading = IPP_DISABLE_FILTERING_INMEM_PARTIAL &&
|
||||
((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem;
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
if(!disableThreading && IPP_BILATERAL_PARALLEL && threads > 1) {
|
||||
if(IPP_BILATERAL_PARALLEL && threads > 1) {
|
||||
bool ok = true;
|
||||
Range range(0, (int)iwDst.m_size.height);
|
||||
ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok);
|
||||
@@ -4336,7 +4308,7 @@ static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, do
|
||||
if(!ok)
|
||||
return false;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, &iwSrc, &iwDst, radius, valSquareSigma, posSquareSigma, ippiFilterBilateralGauss, ippDistNormL1, ippBorder);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), ippBorder);
|
||||
}
|
||||
}
|
||||
catch (::ipp::IwException)
|
||||
|
||||
@@ -962,19 +962,18 @@ static bool ipp_getThreshVal_Otsu_8u( const unsigned char* _src, int step, Size
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_VERSION_X100 >= 810
|
||||
int ippStatus = -1;
|
||||
// Performance degradations
|
||||
#if IPP_VERSION_X100 >= 201800
|
||||
IppiSize srcSize = { size.width, size.height };
|
||||
CV_SUPPRESS_DEPRECATED_START
|
||||
ippStatus = CV_INSTRUMENT_FUN_IPP(ippiComputeThreshold_Otsu_8u_C1R, _src, step, srcSize, &thresh);
|
||||
CV_SUPPRESS_DEPRECATED_END
|
||||
|
||||
if(ippStatus >= 0)
|
||||
return true;
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiComputeThreshold_Otsu_8u_C1R, _src, step, srcSize, &thresh) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(_src); CV_UNUSED(step); CV_UNUSED(size); CV_UNUSED(thresh);
|
||||
#endif
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -992,7 +991,7 @@ getThreshVal_Otsu_8u( const Mat& _src )
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
unsigned char thresh;
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 810, ipp_getThreshVal_Otsu_8u(_src.ptr(), step, size, thresh), thresh);
|
||||
CV_IPP_RUN_FAST(ipp_getThreshVal_Otsu_8u(_src.ptr(), step, size, thresh), thresh);
|
||||
#endif
|
||||
|
||||
const int N = 256;
|
||||
|
||||
Reference in New Issue
Block a user