1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Update for IPP for OpenCV 2017u2 integration;

Updated integrations for:
cv::split
cv::merge
cv::insertChannel
cv::extractChannel
cv::Mat::convertTo - now with scaled conversions support
cv::LUT - disabled due to performance issues
Mat::copyTo
Mat::setTo
cv::flip
cv::copyMakeBorder - currently disabled
cv::polarToCart
cv::pow - ipp pow function was removed due to performance issues
cv::hal::magnitude32f/64f - disabled for <= SSE42, poor performance
cv::countNonZero
cv::minMaxIdx
cv::norm
cv::canny - new integration. Disabled for threaded;
cv::cornerHarris
cv::boxFilter
cv::bilateralFilter
cv::integral
This commit is contained in:
Pavel Vlasov
2017-04-21 14:52:45 +03:00
parent f1c8094f5f
commit 11c2ffaf1c
21 changed files with 1392 additions and 1245 deletions
+79 -77
View File
@@ -51,14 +51,6 @@
#pragma warning( disable: 4127 ) // conditional expression is constant
#endif
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700)
#define USE_IPP_CANNY 1
#else
#define USE_IPP_CANNY 0
#endif
namespace cv
{
@@ -66,73 +58,79 @@ static void CannyImpl(Mat& dx_, Mat& dy_, Mat& _dst, double low_thresh, double h
#ifdef HAVE_IPP
template <bool useCustomDeriv>
static bool ippCanny(const Mat& _src, const Mat& dx_, const Mat& dy_, Mat& _dst, float low, float high)
static bool ipp_Canny(const Mat& src , const Mat& dx_, const Mat& dy_, Mat& dst, float low, float high, bool L2gradient, int aperture_size)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
#if USE_IPP_CANNY
if (!useCustomDeriv && _src.isSubmatrix())
return false; // IPP Sobel doesn't support transparent ROI border
#if IPP_DISABLE_PERF_CANNY_MT
if(cv::getNumThreads()>1)
return false;
#endif
int size = 0, size1 = 0;
IppiSize roi = { _src.cols, _src.rows };
::ipp::IwiSize size(dst.cols, dst.rows);
IppDataType type = ippiGetDataType(dst.depth());
int channels = dst.channels();
IppNormType norm = (L2gradient)?ippNormL2:ippNormL1;
if (ippiCannyGetSize(roi, &size) < 0)
if(size.width <= 3 || size.height <= 3)
return false;
if (!useCustomDeriv)
if(channels != 1)
return false;
if(type != ipp8u)
return false;
if(src.empty())
{
#if IPP_VERSION_X100 < 900
if (ippiFilterSobelNegVertGetBufferSize_8u16s_C1R(roi, ippMskSize3x3, &size1) < 0)
return false;
size = std::max(size, size1);
if (ippiFilterSobelHorizGetBufferSize_8u16s_C1R(roi, ippMskSize3x3, &size1) < 0)
return false;
#else
if (ippiFilterSobelNegVertBorderGetBufferSize(roi, ippMskSize3x3, ipp8u, ipp16s, 1, &size1) < 0)
return false;
size = std::max(size, size1);
if (ippiFilterSobelHorizBorderGetBufferSize(roi, ippMskSize3x3, ipp8u, ipp16s, 1, &size1) < 0)
return false;
#endif
size = std::max(size, size1);
}
try
{
::ipp::IwiImage iwSrcDx;
::ipp::IwiImage iwSrcDy;
::ipp::IwiImage iwDst;
AutoBuffer<uchar> buf(size + 64);
uchar* buffer = alignPtr((uchar*)buf, 32);
ippiGetImage(dx_, iwSrcDx);
ippiGetImage(dy_, iwSrcDy);
ippiGetImage(dst, iwDst);
Mat dx, dy;
if (!useCustomDeriv)
{
Mat _dx(_src.rows, _src.cols, CV_16S);
if( CV_INSTRUMENT_FUN_IPP(ippiFilterSobelNegVertBorder_8u16s_C1R, _src.ptr(), (int)_src.step,
_dx.ptr<short>(), (int)_dx.step, roi,
ippMskSize3x3, ippBorderRepl, 0, buffer) < 0 )
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCannyDeriv, &iwSrcDx, &iwSrcDy, &iwDst, norm, low, high);
}
catch (::ipp::IwException ex)
{
return false;
Mat _dy(_src.rows, _src.cols, CV_16S);
if( CV_INSTRUMENT_FUN_IPP(ippiFilterSobelHorizBorder_8u16s_C1R, _src.ptr(), (int)_src.step,
_dy.ptr<short>(), (int)_dy.step, roi,
ippMskSize3x3, ippBorderRepl, 0, buffer) < 0 )
return false;
swap(dx, _dx);
swap(dy, _dy);
}
}
else
{
dx = dx_;
dy = dy_;
IppiMaskSize kernel;
if(aperture_size == 3)
kernel = ippMskSize3x3;
else if(aperture_size == 5)
kernel = ippMskSize5x5;
else
return false;
try
{
::ipp::IwiImage iwSrc;
::ipp::IwiImage iwDst;
ippiGetImage(src, iwSrc);
ippiGetImage(dst, iwDst);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterCanny, &iwSrc, &iwDst, ippFilterSobel, kernel, norm, low, high, ippBorderRepl);
}
catch (::ipp::IwException)
{
return false;
}
}
if( CV_INSTRUMENT_FUN_IPP(ippiCanny_16s8u_C1R, dx.ptr<short>(), (int)dx.step,
dy.ptr<short>(), (int)dy.step,
_dst.ptr(), (int)_dst.step, roi, low, high, buffer) < 0 )
return false;
return true;
#else
CV_UNUSED(_src); CV_UNUSED(dx_); CV_UNUSED(dy_); CV_UNUSED(_dst); CV_UNUSED(low); CV_UNUSED(high);
CV_UNUSED(src); CV_UNUSED(dx_); CV_UNUSED(dy_); CV_UNUSED(dst); CV_UNUSED(low); CV_UNUSED(high); CV_UNUSED(L2gradient); CV_UNUSED(aperture_size);
return false;
#endif
}
@@ -318,6 +316,8 @@ public:
// In sobel transform we calculate ksize2 extra lines for the first and last rows of each slice
// because IPPDerivSobel expects only isolated ROIs, in contrast with the opencv version which
// uses the pixels outside of the ROI to form a border.
//
// TODO: statement above is not true anymore, so adjustments may be required
int ksize2 = aperture_size / 2;
// If Scharr filter: aperture_size is 3 and ksize2 is 1
if(aperture_size == -1)
@@ -882,18 +882,18 @@ void Canny( InputArray _src, OutputArray _dst,
return;
#endif
CV_IPP_RUN(USE_IPP_CANNY && (aperture_size == 3 && !L2gradient && 1 == cn), ippCanny<false>(src, Mat(), Mat(), dst, (float)low_thresh, (float)high_thresh))
CV_IPP_RUN_FAST(ipp_Canny(src, Mat(), Mat(), dst, (float)low_thresh, (float)high_thresh, L2gradient, aperture_size))
if (L2gradient)
{
low_thresh = std::min(32767.0, low_thresh);
high_thresh = std::min(32767.0, high_thresh);
if (L2gradient)
{
low_thresh = std::min(32767.0, low_thresh);
high_thresh = std::min(32767.0, high_thresh);
if (low_thresh > 0) low_thresh *= low_thresh;
if (high_thresh > 0) high_thresh *= high_thresh;
}
int low = cvFloor(low_thresh);
int high = cvFloor(high_thresh);
if (low_thresh > 0) low_thresh *= low_thresh;
if (high_thresh > 0) high_thresh *= high_thresh;
}
int low = cvFloor(low_thresh);
int high = cvFloor(high_thresh);
ptrdiff_t mapstep = src.cols + 2;
AutoBuffer<uchar> buffer((src.cols+2)*(src.rows+2) + cn * mapstep * 3 * sizeof(int));
@@ -938,15 +938,15 @@ int high = cvFloor(high_thresh);
{
m = borderPeaksParallel.front();
borderPeaksParallel.pop();
if (!m[-1]) CANNY_PUSH_SERIAL(m - 1);
if (!m[1]) CANNY_PUSH_SERIAL(m + 1);
if (!m[-mapstep-1]) CANNY_PUSH_SERIAL(m - mapstep - 1);
if (!m[-mapstep]) CANNY_PUSH_SERIAL(m - mapstep);
if (!m[-mapstep+1]) CANNY_PUSH_SERIAL(m - mapstep + 1);
if (!m[mapstep-1]) CANNY_PUSH_SERIAL(m + mapstep - 1);
if (!m[mapstep]) CANNY_PUSH_SERIAL(m + mapstep);
if (!m[mapstep+1]) CANNY_PUSH_SERIAL(m + mapstep + 1);
}
if (!m[-1]) CANNY_PUSH_SERIAL(m - 1);
if (!m[1]) CANNY_PUSH_SERIAL(m + 1);
if (!m[-mapstep-1]) CANNY_PUSH_SERIAL(m - mapstep - 1);
if (!m[-mapstep]) CANNY_PUSH_SERIAL(m - mapstep);
if (!m[-mapstep+1]) CANNY_PUSH_SERIAL(m - mapstep + 1);
if (!m[mapstep-1]) CANNY_PUSH_SERIAL(m + mapstep - 1);
if (!m[mapstep]) CANNY_PUSH_SERIAL(m + mapstep);
if (!m[mapstep+1]) CANNY_PUSH_SERIAL(m + mapstep + 1);
}
parallel_for_(Range(0, dst.rows), finalPass(map, dst, mapstep), dst.total()/(double)(1<<16));
}
@@ -955,6 +955,8 @@ void Canny( InputArray _dx, InputArray _dy, OutputArray _dst,
double low_thresh, double high_thresh,
bool L2gradient )
{
CV_INSTRUMENT_REGION()
CV_Assert(_dx.dims() == 2);
CV_Assert(_dx.type() == CV_16SC1 || _dx.type() == CV_16SC3);
CV_Assert(_dy.type() == _dx.type());
@@ -975,7 +977,7 @@ void Canny( InputArray _dx, InputArray _dy, OutputArray _dst,
Mat dx = _dx.getMat();
Mat dy = _dy.getMat();
CV_IPP_RUN(USE_IPP_CANNY && (!L2gradient && 1 == cn), ippCanny<true>(Mat(), dx, dy, dst, (float)low_thresh, (float)high_thresh))
CV_IPP_RUN_FAST(ipp_Canny(Mat(), dx, dy, dst, (float)low_thresh, (float)high_thresh, L2gradient, 0))
if (cn > 1)
{
+14 -20
View File
@@ -604,9 +604,9 @@ namespace cv
{
static bool ipp_cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
{
#if IPP_VERSION_X100 >= 800
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 800
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
@@ -703,15 +703,11 @@ void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, in
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
static bool ipp_cornerHarris( Mat &src, Mat &dst, int blockSize, int ksize, double k, int borderType )
{
#if IPP_VERSION_X100 >= 810
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
{
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
int borderTypeNI = borderType & ~BORDER_ISOLATED;
@@ -734,17 +730,17 @@ static bool ipp_cornerHarris( InputArray _src, OutputArray _dst, int blockSize,
if (ippiHarrisCornerGetBufferSize(roisize, masksize, blockSize, datatype, cn, &bufsize) >= 0)
{
Ipp8u * buffer = ippsMalloc_8u(bufsize);
Ipp8u * buffer = (Ipp8u*)CV_IPP_MALLOC(bufsize);
IppiDifferentialKernel filterType = ksize > 0 ? ippFilterSobel : ippFilterScharr;
IppiBorderType borderTypeIpp = borderTypeNI == BORDER_CONSTANT ? ippBorderConst : ippBorderRepl;
IppStatus status = (IppStatus)-1;
if (depth == CV_8U)
status = CV_INSTRUMENT_FUN_IPP(ippiHarrisCorner_8u32f_C1R,((const Ipp8u *)src.data, (int)src.step, (Ipp32f *)dst.data, (int)dst.step, roisize,
filterType, masksize, blockSize, (Ipp32f)k, (Ipp32f)scale, borderTypeIpp, 0, buffer));
status = CV_INSTRUMENT_FUN_IPP(ippiHarrisCorner_8u32f_C1R, (const Ipp8u *)src.data, (int)src.step, (Ipp32f *)dst.data, (int)dst.step, roisize,
filterType, masksize, blockSize, (Ipp32f)k, (Ipp32f)scale, borderTypeIpp, 0, buffer);
else if (depth == CV_32F)
status = CV_INSTRUMENT_FUN_IPP(ippiHarrisCorner_32f_C1R,((const Ipp32f *)src.data, (int)src.step, (Ipp32f *)dst.data, (int)dst.step, roisize,
filterType, masksize, blockSize, (Ipp32f)k, (Ipp32f)scale, borderTypeIpp, 0, buffer));
status = CV_INSTRUMENT_FUN_IPP(ippiHarrisCorner_32f_C1R, (const Ipp32f *)src.data, (int)src.step, (Ipp32f *)dst.data, (int)dst.step, roisize,
filterType, masksize, blockSize, (Ipp32f)k, (Ipp32f)scale, borderTypeIpp, 0, buffer);
ippsFree(buffer);
if (status >= 0)
@@ -756,7 +752,7 @@ static bool ipp_cornerHarris( InputArray _src, OutputArray _dst, int blockSize,
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(blockSize); CV_UNUSED(ksize); CV_UNUSED(k); CV_UNUSED(borderType);
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(blockSize); CV_UNUSED(ksize); CV_UNUSED(k); CV_UNUSED(borderType);
#endif
return false;
}
@@ -770,19 +766,17 @@ void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksi
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, k, borderType, HARRIS))
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
#ifdef HAVE_IPP
int borderTypeNI = borderType & ~BORDER_ISOLATED;
bool isolated = (borderType & BORDER_ISOLATED) != 0;
#endif
CV_IPP_RUN(((ksize == 3 || ksize == 5) && (_src.type() == CV_8UC1 || _src.type() == CV_32FC1) &&
(borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE) && CV_MAT_CN(_src.type()) == 1 &&
(!_src.isSubmatrix() || isolated)) && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK, ipp_cornerHarris( _src, _dst, blockSize, ksize, k, borderType ));
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
(!_src.isSubmatrix() || isolated)) && IPP_VERSION_X100 >= 810, ipp_cornerHarris( src, dst, blockSize, ksize, k, borderType ));
cornerEigenValsVecs( src, dst, blockSize, ksize, HARRIS, k, borderType );
}
+7 -7
View File
@@ -1360,14 +1360,14 @@ struct RowVec_32f
{
kernel = _kernel;
haveSSE = checkHardwareSupport(CV_CPU_SSE);
#if defined USE_IPP_SEP_FILTERS && IPP_DISABLE_BLOCK
#if defined USE_IPP_SEP_FILTERS
bufsz = -1;
#endif
}
int operator()(const uchar* _src, uchar* _dst, int width, int cn) const
{
#if defined USE_IPP_SEP_FILTERS && IPP_DISABLE_BLOCK
#if defined USE_IPP_SEP_FILTERS
CV_IPP_CHECK()
{
int ret = ippiOperator(_src, _dst, width, cn);
@@ -1408,7 +1408,7 @@ struct RowVec_32f
Mat kernel;
bool haveSSE;
#if defined USE_IPP_SEP_FILTERS && IPP_DISABLE_BLOCK
#if defined USE_IPP_SEP_FILTERS
private:
mutable int bufsz;
int ippiOperator(const uchar* _src, uchar* _dst, int width, int cn) const
@@ -1436,10 +1436,10 @@ private:
float borderValue[] = {0.f, 0.f, 0.f};
// here is the trick. IPP needs border type and extrapolates the row. We did it already.
// So we pass anchor=0 and ignore the right tail of results since they are incorrect there.
if( (cn == 1 && CV_INSTRUMENT_FUN_IPP(ippiFilterRowBorderPipeline_32f_C1R,(src, step, &dst, roisz, _kx, _ksize, 0,
ippBorderRepl, borderValue[0], bufptr)) < 0) ||
(cn == 3 && CV_INSTRUMENT_FUN_IPP(ippiFilterRowBorderPipeline_32f_C3R,(src, step, &dst, roisz, _kx, _ksize, 0,
ippBorderRepl, borderValue, bufptr)) < 0))
if( (cn == 1 && CV_INSTRUMENT_FUN_IPP(ippiFilterRowBorderPipeline_32f_C1R, src, step, &dst, roisz, _kx, _ksize, 0,
ippBorderRepl, borderValue[0], bufptr) < 0) ||
(cn == 3 && CV_INSTRUMENT_FUN_IPP(ippiFilterRowBorderPipeline_32f_C3R, src, step, &dst, roisz, _kx, _ksize, 0,
ippBorderRepl, borderValue, bufptr) < 0))
{
setIppErrorStatus();
return 0;
+8 -8
View File
@@ -96,7 +96,7 @@ HoughLinesStandard( const Mat& img, float rho, float theta,
int numangle = cvRound((max_theta - min_theta) / theta);
int numrho = cvRound(((width + height) * 2 + 1) / rho);
#if defined HAVE_IPP && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if defined HAVE_IPP && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_HOUGH
CV_IPP_CHECK()
{
IppiSize srcSize = { width, height };
@@ -108,8 +108,8 @@ HoughLinesStandard( const Mat& img, float rho, float theta,
int linesCount = 0;
lines.resize(ipp_linesMax);
IppStatus ok = ippiHoughLineGetSize_8u_C1R(srcSize, delta, ipp_linesMax, &bufferSize);
Ipp8u* buffer = ippsMalloc_8u(bufferSize);
if (ok >= 0) {ok = CV_INSTRUMENT_FUN_IPP(ippiHoughLine_Region_8u32f_C1R,(image, step, srcSize, (IppPointPolar*) &lines[0], dstRoi, ipp_linesMax, &linesCount, delta, threshold, buffer))};
Ipp8u* buffer = ippsMalloc_8u_L(bufferSize);
if (ok >= 0) {ok = CV_INSTRUMENT_FUN_IPP(ippiHoughLine_Region_8u32f_C1R, image, step, srcSize, (IppPointPolar*) &lines[0], dstRoi, ipp_linesMax, &linesCount, delta, threshold, buffer);};
ippsFree(buffer);
if (ok >= 0)
{
@@ -429,7 +429,7 @@ HoughLinesProbabilistic( Mat& image,
int numangle = cvRound(CV_PI / theta);
int numrho = cvRound(((width + height) * 2 + 1) / rho);
#if defined HAVE_IPP && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if defined HAVE_IPP && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_HOUGH
CV_IPP_CHECK()
{
IppiSize srcSize = { width, height };
@@ -440,12 +440,12 @@ HoughLinesProbabilistic( Mat& image,
int linesCount = 0;
lines.resize(ipp_linesMax);
IppStatus ok = ippiHoughProbLineGetSize_8u_C1R(srcSize, delta, &specSize, &bufferSize);
Ipp8u* buffer = ippsMalloc_8u(bufferSize);
pSpec = (IppiHoughProbSpec*) malloc(specSize);
Ipp8u* buffer = ippsMalloc_8u_L(bufferSize);
pSpec = (IppiHoughProbSpec*) ippsMalloc_8u_L(specSize);
if (ok >= 0) ok = ippiHoughProbLineInit_8u32f_C1R(srcSize, delta, ippAlgHintNone, pSpec);
if (ok >= 0) {ok = CV_INSTRUMENT_FUN_IPP(ippiHoughProbLine_8u32f_C1R,(image.data, image.step, srcSize, threshold, lineLength, lineGap, (IppiPoint*) &lines[0], ipp_linesMax, &linesCount, buffer, pSpec))};
if (ok >= 0) {ok = CV_INSTRUMENT_FUN_IPP(ippiHoughProbLine_8u32f_C1R, image.data, (int)image.step, srcSize, threshold, lineLength, lineGap, (IppiPoint*) &lines[0], ipp_linesMax, &linesCount, buffer, pSpec);};
free(pSpec);
ippsFree(pSpec);
ippsFree(buffer);
if (ok >= 0)
{
+159 -144
View File
@@ -556,13 +556,94 @@ static bool ocl_moments( InputArray _src, Moments& m, bool binary)
m.m03 += mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym));
}
completeMomentState( &m );
return true;
}
#endif
}
#ifdef HAVE_IPP
typedef IppStatus (CV_STDCALL * ippiMoments)(const void* pSrc, int srcStep, IppiSize roiSize, IppiMomentState_64f* pCtx);
static bool ipp_moments(Mat &src, Moments &m )
{
#if IPP_VERSION_X100 >= 900
CV_INSTRUMENT_REGION_IPP()
IppiSize roi = { src.cols, src.rows };
IppiPoint point = { 0, 0 };
int type = src.type();
IppStatus ippStatus;
IppAutoBuffer<IppiMomentState_64f> state;
int stateSize = 0;
ippiMoments ippiMoments64f =
(type == CV_8UC1)?(ippiMoments)ippiMoments64f_8u_C1R:
(type == CV_16UC1)?(ippiMoments)ippiMoments64f_16u_C1R:
(type == CV_32FC1)?(ippiMoments)ippiMoments64f_32f_C1R:
NULL;
if(!ippiMoments64f)
return false;
ippStatus = ippiMomentGetStateSize_64f(ippAlgHintAccurate, &stateSize);
if(ippStatus < 0)
return false;
if(!state.allocate(stateSize) && stateSize)
return false;
ippStatus = ippiMomentInit_64f(state, ippAlgHintAccurate);
if(ippStatus < 0)
return false;
ippStatus = CV_INSTRUMENT_FUN_IPP(ippiMoments64f, src.ptr<Ipp8u>(), (int)src.step, roi, state);
if(ippStatus < 0)
return false;
ippStatus = ippiGetSpatialMoment_64f(state, 0, 0, 0, point, &m.m00);
if(ippStatus < 0)
return false;
ippiGetSpatialMoment_64f(state, 1, 0, 0, point, &m.m10);
ippiGetSpatialMoment_64f(state, 0, 1, 0, point, &m.m01);
ippiGetSpatialMoment_64f(state, 2, 0, 0, point, &m.m20);
ippiGetSpatialMoment_64f(state, 1, 1, 0, point, &m.m11);
ippiGetSpatialMoment_64f(state, 0, 2, 0, point, &m.m02);
ippiGetSpatialMoment_64f(state, 3, 0, 0, point, &m.m30);
ippiGetSpatialMoment_64f(state, 2, 1, 0, point, &m.m21);
ippiGetSpatialMoment_64f(state, 1, 2, 0, point, &m.m12);
ippiGetSpatialMoment_64f(state, 0, 3, 0, point, &m.m03);
ippStatus = ippiGetCentralMoment_64f(state, 2, 0, 0, &m.mu20);
if(ippStatus < 0)
return false;
ippiGetCentralMoment_64f(state, 1, 1, 0, &m.mu11);
ippiGetCentralMoment_64f(state, 0, 2, 0, &m.mu02);
ippiGetCentralMoment_64f(state, 3, 0, 0, &m.mu30);
ippiGetCentralMoment_64f(state, 2, 1, 0, &m.mu21);
ippiGetCentralMoment_64f(state, 1, 2, 0, &m.mu12);
ippiGetCentralMoment_64f(state, 0, 3, 0, &m.mu03);
ippStatus = ippiGetNormalizedCentralMoment_64f(state, 2, 0, 0, &m.nu20);
if(ippStatus < 0)
return false;
ippiGetNormalizedCentralMoment_64f(state, 1, 1, 0, &m.nu11);
ippiGetNormalizedCentralMoment_64f(state, 0, 2, 0, &m.nu02);
ippiGetNormalizedCentralMoment_64f(state, 3, 0, 0, &m.nu30);
ippiGetNormalizedCentralMoment_64f(state, 2, 1, 0, &m.nu21);
ippiGetNormalizedCentralMoment_64f(state, 1, 2, 0, &m.nu12);
ippiGetNormalizedCentralMoment_64f(state, 0, 3, 0, &m.nu03);
return true;
#else
CV_UNUSED(src); CV_UNUSED(m);
return false;
#endif
}
#endif
}
cv::Moments cv::moments( InputArray _src, bool binary )
{
@@ -579,159 +660,93 @@ cv::Moments cv::moments( InputArray _src, bool binary )
return m;
#ifdef HAVE_OPENCL
if( !(ocl::useOpenCL() && type == CV_8UC1 &&
_src.isUMat() && ocl_moments(_src, m, binary)) )
CV_OCL_RUN_(type == CV_8UC1 && _src.isUMat(), ocl_moments(_src, m, binary), m);
#endif
Mat mat = _src.getMat();
if( mat.checkVector(2) >= 0 && (depth == CV_32F || depth == CV_32S))
return contourMoments(mat);
if( cn > 1 )
CV_Error( CV_StsBadArg, "Invalid image type (must be single-channel)" );
CV_IPP_RUN(!binary, ipp_moments(mat, m), m);
if( binary || depth == CV_8U )
func = momentsInTile<uchar, int, int>;
else if( depth == CV_16U )
func = momentsInTile<ushort, int, int64>;
else if( depth == CV_16S )
func = momentsInTile<short, int, int64>;
else if( depth == CV_32F )
func = momentsInTile<float, double, double>;
else if( depth == CV_64F )
func = momentsInTile<double, double, double>;
else
CV_Error( CV_StsUnsupportedFormat, "" );
Mat src0(mat);
for( int y = 0; y < size.height; y += TILE_SIZE )
{
Mat mat = _src.getMat();
if( mat.checkVector(2) >= 0 && (depth == CV_32F || depth == CV_32S))
return contourMoments(mat);
Size tileSize;
tileSize.height = std::min(TILE_SIZE, size.height - y);
if( cn > 1 )
CV_Error( CV_StsBadArg, "Invalid image type (must be single-channel)" );
#if IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
CV_IPP_CHECK()
for( int x = 0; x < size.width; x += TILE_SIZE )
{
if (!binary)
tileSize.width = std::min(TILE_SIZE, size.width - x);
Mat src(src0, cv::Rect(x, y, tileSize.width, tileSize.height));
if( binary )
{
IppiSize roi = { mat.cols, mat.rows };
IppiMomentState_64f * moment = NULL;
// ippiMomentInitAlloc_64f, ippiMomentFree_64f are deprecated in 8.1, but there are not another way
// to initialize IppiMomentState_64f. When GetStateSize and Init functions will appear we have to
// change our code.
CV_SUPPRESS_DEPRECATED_START
if (ippiMomentInitAlloc_64f(&moment, ippAlgHintAccurate) >= 0)
{
typedef IppStatus (CV_STDCALL * ippiMoments)(const void * pSrc, int srcStep, IppiSize roiSize, IppiMomentState_64f* pCtx);
ippiMoments ippFunc =
type == CV_8UC1 ? (ippiMoments)ippiMoments64f_8u_C1R :
type == CV_16UC1 ? (ippiMoments)ippiMoments64f_16u_C1R :
type == CV_32FC1? (ippiMoments)ippiMoments64f_32f_C1R : 0;
if (ippFunc)
{
if (CV_INSTRUMENT_FUN_IPP(ippFunc,(mat.data, (int)mat.step, roi, moment)) >= 0)
{
IppiPoint point = { 0, 0 };
ippiGetSpatialMoment_64f(moment, 0, 0, 0, point, &m.m00);
ippiGetSpatialMoment_64f(moment, 1, 0, 0, point, &m.m10);
ippiGetSpatialMoment_64f(moment, 0, 1, 0, point, &m.m01);
ippiGetSpatialMoment_64f(moment, 2, 0, 0, point, &m.m20);
ippiGetSpatialMoment_64f(moment, 1, 1, 0, point, &m.m11);
ippiGetSpatialMoment_64f(moment, 0, 2, 0, point, &m.m02);
ippiGetSpatialMoment_64f(moment, 3, 0, 0, point, &m.m30);
ippiGetSpatialMoment_64f(moment, 2, 1, 0, point, &m.m21);
ippiGetSpatialMoment_64f(moment, 1, 2, 0, point, &m.m12);
ippiGetSpatialMoment_64f(moment, 0, 3, 0, point, &m.m03);
ippiGetCentralMoment_64f(moment, 2, 0, 0, &m.mu20);
ippiGetCentralMoment_64f(moment, 1, 1, 0, &m.mu11);
ippiGetCentralMoment_64f(moment, 0, 2, 0, &m.mu02);
ippiGetCentralMoment_64f(moment, 3, 0, 0, &m.mu30);
ippiGetCentralMoment_64f(moment, 2, 1, 0, &m.mu21);
ippiGetCentralMoment_64f(moment, 1, 2, 0, &m.mu12);
ippiGetCentralMoment_64f(moment, 0, 3, 0, &m.mu03);
ippiGetNormalizedCentralMoment_64f(moment, 2, 0, 0, &m.nu20);
ippiGetNormalizedCentralMoment_64f(moment, 1, 1, 0, &m.nu11);
ippiGetNormalizedCentralMoment_64f(moment, 0, 2, 0, &m.nu02);
ippiGetNormalizedCentralMoment_64f(moment, 3, 0, 0, &m.nu30);
ippiGetNormalizedCentralMoment_64f(moment, 2, 1, 0, &m.nu21);
ippiGetNormalizedCentralMoment_64f(moment, 1, 2, 0, &m.nu12);
ippiGetNormalizedCentralMoment_64f(moment, 0, 3, 0, &m.nu03);
ippiMomentFree_64f(moment);
CV_IMPL_ADD(CV_IMPL_IPP);
return m;
}
setIppErrorStatus();
}
ippiMomentFree_64f(moment);
}
else
setIppErrorStatus();
CV_SUPPRESS_DEPRECATED_END
cv::Mat tmp(tileSize, CV_8U, nzbuf);
cv::compare( src, 0, tmp, CV_CMP_NE );
src = tmp;
}
}
#endif
if( binary || depth == CV_8U )
func = momentsInTile<uchar, int, int>;
else if( depth == CV_16U )
func = momentsInTile<ushort, int, int64>;
else if( depth == CV_16S )
func = momentsInTile<short, int, int64>;
else if( depth == CV_32F )
func = momentsInTile<float, double, double>;
else if( depth == CV_64F )
func = momentsInTile<double, double, double>;
else
CV_Error( CV_StsUnsupportedFormat, "" );
double mom[10];
func( src, mom );
Mat src0(mat);
for( int y = 0; y < size.height; y += TILE_SIZE )
{
Size tileSize;
tileSize.height = std::min(TILE_SIZE, size.height - y);
for( int x = 0; x < size.width; x += TILE_SIZE )
if(binary)
{
tileSize.width = std::min(TILE_SIZE, size.width - x);
Mat src(src0, cv::Rect(x, y, tileSize.width, tileSize.height));
if( binary )
{
cv::Mat tmp(tileSize, CV_8U, nzbuf);
cv::compare( src, 0, tmp, CV_CMP_NE );
src = tmp;
}
double mom[10];
func( src, mom );
if(binary)
{
double s = 1./255;
for( int k = 0; k < 10; k++ )
mom[k] *= s;
}
double xm = x * mom[0], ym = y * mom[0];
// accumulate moments computed in each tile
// + m00 ( = m00' )
m.m00 += mom[0];
// + m10 ( = m10' + x*m00' )
m.m10 += mom[1] + xm;
// + m01 ( = m01' + y*m00' )
m.m01 += mom[2] + ym;
// + m20 ( = m20' + 2*x*m10' + x*x*m00' )
m.m20 += mom[3] + x * (mom[1] * 2 + xm);
// + m11 ( = m11' + x*m01' + y*m10' + x*y*m00' )
m.m11 += mom[4] + x * (mom[2] + ym) + y * mom[1];
// + m02 ( = m02' + 2*y*m01' + y*y*m00' )
m.m02 += mom[5] + y * (mom[2] * 2 + ym);
// + m30 ( = m30' + 3*x*m20' + 3*x*x*m10' + x*x*x*m00' )
m.m30 += mom[6] + x * (3. * mom[3] + x * (3. * mom[1] + xm));
// + m21 ( = m21' + x*(2*m11' + 2*y*m10' + x*m01' + x*y*m00') + y*m20')
m.m21 += mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3];
// + m12 ( = m12' + y*(2*m11' + 2*x*m01' + y*m10' + x*y*m00') + x*m02')
m.m12 += mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5];
// + m03 ( = m03' + 3*y*m02' + 3*y*y*m01' + y*y*y*m00' )
m.m03 += mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym));
double s = 1./255;
for( int k = 0; k < 10; k++ )
mom[k] *= s;
}
double xm = x * mom[0], ym = y * mom[0];
// accumulate moments computed in each tile
// + m00 ( = m00' )
m.m00 += mom[0];
// + m10 ( = m10' + x*m00' )
m.m10 += mom[1] + xm;
// + m01 ( = m01' + y*m00' )
m.m01 += mom[2] + ym;
// + m20 ( = m20' + 2*x*m10' + x*x*m00' )
m.m20 += mom[3] + x * (mom[1] * 2 + xm);
// + m11 ( = m11' + x*m01' + y*m10' + x*y*m00' )
m.m11 += mom[4] + x * (mom[2] + ym) + y * mom[1];
// + m02 ( = m02' + 2*y*m01' + y*y*m00' )
m.m02 += mom[5] + y * (mom[2] * 2 + ym);
// + m30 ( = m30' + 3*x*m20' + 3*x*x*m10' + x*x*x*m00' )
m.m30 += mom[6] + x * (3. * mom[3] + x * (3. * mom[1] + xm));
// + m21 ( = m21' + x*(2*m11' + 2*y*m10' + x*m01' + x*y*m00') + y*m20')
m.m21 += mom[7] + x * (2 * (mom[4] + y * mom[1]) + x * (mom[2] + ym)) + y * mom[3];
// + m12 ( = m12' + y*(2*m11' + 2*x*m01' + y*m10' + x*y*m00') + x*m02')
m.m12 += mom[8] + y * (2 * (mom[4] + x * mom[2]) + y * (mom[1] + xm)) + x * mom[5];
// + m03 ( = m03' + 3*y*m02' + 3*y*y*m01' + y*y*y*m00' )
m.m03 += mom[9] + y * (3. * mom[5] + y * (3. * mom[2] + ym));
}
}
+6 -6
View File
@@ -1200,7 +1200,7 @@ static bool ipp_pyrdown( InputArray _src, OutputArray _dst, const Size& _dsz, in
{
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if IPP_VERSION_X100 >= 810 && !IPP_DISABLE_PYRAMIDS_DOWN
Size dsz = _dsz.area() == 0 ? Size((_src.cols() + 1)/2, (_src.rows() + 1)/2) : _dsz;
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
@@ -1235,7 +1235,7 @@ static bool ipp_pyrdown( InputArray _src, OutputArray _dst, const Size& _dsz, in
CV_SUPPRESS_DEPRECATED_END
if (ok >= 0)
{
Ipp8u* buffer = ippsMalloc_8u(bufferSize);
Ipp8u* buffer = ippsMalloc_8u_L(bufferSize);
ok = pyrUpFunc(src.data, (int) src.step, dst.data, (int) dst.step, srcRoi, buffer);
ippsFree(buffer);
@@ -1388,7 +1388,7 @@ static bool ipp_pyrup( InputArray _src, OutputArray _dst, const Size& _dsz, int
{
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if IPP_VERSION_X100 >= 810 && !IPP_DISABLE_PYRAMIDS_UP
Size sz = _src.dims() <= 2 ? _src.size() : Size();
Size dsz = _dsz.area() == 0 ? Size(_src.cols()*2, _src.rows()*2) : _dsz;
@@ -1421,7 +1421,7 @@ static bool ipp_pyrup( InputArray _src, OutputArray _dst, const Size& _dsz, int
CV_SUPPRESS_DEPRECATED_END
if (ok >= 0)
{
Ipp8u* buffer = ippsMalloc_8u(bufferSize);
Ipp8u* buffer = ippsMalloc_8u_L(bufferSize);
ok = pyrUpFunc(src.data, (int) src.step, dst.data, (int) dst.step, srcRoi, buffer);
ippsFree(buffer);
@@ -1496,7 +1496,7 @@ static bool ipp_buildpyramid( InputArray _src, OutputArrayOfArrays _dst, int max
{
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if IPP_VERSION_X100 >= 810 && !IPP_DISABLE_PYRAMIDS_BUILD
Mat src = _src.getMat();
_dst.create( maxlevel + 1, 1, 0 );
_dst.getMatRef(0) = src;
@@ -1626,7 +1626,7 @@ void cv::buildPyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel,
int i=1;
CV_IPP_RUN(((IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK) && ((borderType & ~BORDER_ISOLATED) == BORDER_DEFAULT && (!_src.isSubmatrix() || ((borderType & BORDER_ISOLATED) != 0)))),
CV_IPP_RUN(((IPP_VERSION_X100 >= 810) && ((borderType & ~BORDER_ISOLATED) == BORDER_DEFAULT && (!_src.isSubmatrix() || ((borderType & BORDER_ISOLATED) != 0)))),
ipp_buildpyramid( _src, _dst, maxlevel, borderType));
for( ; i <= maxlevel; i++ )
+165 -153
View File
@@ -1734,98 +1734,84 @@ namespace cv
}
#endif
// TODO: IPP performance regression
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_boxfilter( InputArray _src, OutputArray _dst, int ddepth,
Size ksize, Point anchor,
bool normalize, int borderType )
static bool ipp_boxfilter(Mat &src, Mat &dst, Size ksize, Point anchor, bool normalize, int borderType)
{
CV_INSTRUMENT_REGION_IPP()
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if( ddepth < 0 )
ddepth = sdepth;
int ippBorderType = borderType & ~BORDER_ISOLATED;
// Problem with SSE42 optimization for 16s
#if IPP_DISABLE_PERF_BOX16S_SSE42
if(src.depth() == CV_16S && !(ipp::getIppFeatures()&ippCPUID_AVX))
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);
Mat src = _src.getMat();
_dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );
Mat dst = _dst.getMat();
if( borderType != BORDER_CONSTANT && normalize && (borderType & BORDER_ISOLATED) != 0 )
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( src.rows == 1 )
ksize.height = 1;
if( src.cols == 1 )
ksize.width = 1;
}
IppStatus status;
Ipp32s bufSize = 0;
IppiSize roiSize = { dst.cols, dst.rows };
IppiSize maskSize = { ksize.width, ksize.height };
IppAutoBuffer<Ipp8u> buffer;
{
if (normalize && !src.isSubmatrix() && ddepth == sdepth &&
(/*ippBorderType == BORDER_REPLICATE ||*/ /* returns ippStsStepErr: Step value is not valid */
ippBorderType == BORDER_CONSTANT) && ocvAnchor == ippAnchor &&
dst.cols != ksize.width && dst.rows != ksize.height) // returns ippStsMaskSizeErr: mask has an illegal value
{
Ipp32s bufSize = 0;
IppiSize roiSize = { dst.cols, dst.rows }, maskSize = { ksize.width, ksize.height };
if(ippiFilterBoxBorderGetBufferSize(roiSize, maskSize, ippType, cn, &bufSize) < 0)
return false;
#define IPP_FILTER_BOX_BORDER(ippType, ippDataType, flavor) \
do \
{ \
if (ippiFilterBoxBorderGetBufferSize(roiSize, maskSize, ippDataType, cn, &bufSize) >= 0) \
{ \
Ipp8u * buffer = ippsMalloc_8u(bufSize); \
ippType borderValue[4] = { 0, 0, 0, 0 }; \
ippBorderType = ippBorderType == BORDER_CONSTANT ? ippBorderConst : ippBorderRepl; \
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiFilterBoxBorder_##flavor, src.ptr<ippType>(), (int)src.step, dst.ptr<ippType>(), \
(int)dst.step, roiSize, maskSize, \
(IppiBorderType)ippBorderType, borderValue, buffer); \
ippsFree(buffer); \
if (status >= 0) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return true; \
} \
} \
} while ((void)0, 0)
buffer.allocate(bufSize);
if (stype == CV_8UC1)
IPP_FILTER_BOX_BORDER(Ipp8u, ipp8u, 8u_C1R);
else if (stype == CV_8UC3)
IPP_FILTER_BOX_BORDER(Ipp8u, ipp8u, 8u_C3R);
else if (stype == CV_8UC4)
IPP_FILTER_BOX_BORDER(Ipp8u, ipp8u, 8u_C4R);
// Oct 2014: performance with BORDER_CONSTANT
//else if (stype == CV_16UC1)
// IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C1R);
else if (stype == CV_16UC3)
IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C3R);
else if (stype == CV_16UC4)
IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C4R);
// Oct 2014: performance with BORDER_CONSTANT
//else if (stype == CV_16SC1)
// IPP_FILTER_BOX_BORDER(Ipp16s, ipp16s, 16s_C1R);
else if (stype == CV_16SC3)
IPP_FILTER_BOX_BORDER(Ipp16s, ipp16s, 16s_C3R);
else if (stype == CV_16SC4)
IPP_FILTER_BOX_BORDER(Ipp16s, ipp16s, 16s_C4R);
else if (stype == CV_32FC1)
IPP_FILTER_BOX_BORDER(Ipp32f, ipp32f, 32f_C1R);
else if (stype == CV_32FC3)
IPP_FILTER_BOX_BORDER(Ipp32f, ipp32f, 32f_C3R);
else if (stype == CV_32FC4)
IPP_FILTER_BOX_BORDER(Ipp32f, ipp32f, 32f_C4R);
#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);\
}
#undef IPP_FILTER_BOX_BORDER
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;
}
#undef IPP_FILTER_BOX_BORDER
return false;
}
}
@@ -1866,19 +1852,7 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
return;
#endif
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
int ippBorderType = borderType & ~BORDER_ISOLATED;
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);
CV_IPP_RUN((normalize && !_src.isSubmatrix() && ddepth == sdepth &&
(/*ippBorderType == BORDER_REPLICATE ||*/ /* returns ippStsStepErr: Step value is not valid */
ippBorderType == BORDER_CONSTANT) && ocvAnchor == ippAnchor &&
_dst.cols() != ksize.width && _dst.rows() != ksize.height),
ipp_boxfilter( _src, _dst, ddepth, ksize, anchor, normalize, borderType));
#endif
CV_IPP_RUN_FAST(ipp_boxfilter(src, dst, ksize, anchor, normalize, borderType));
Point ofs;
Size wsz(src.cols, src.rows);
@@ -3691,53 +3665,6 @@ private:
float *space_weight, *color_weight;
};
#if defined (HAVE_IPP) && IPP_DISABLE_BLOCK
class IPPBilateralFilter_8u_Invoker :
public ParallelLoopBody
{
public:
IPPBilateralFilter_8u_Invoker(Mat &_src, Mat &_dst, double _sigma_color, double _sigma_space, int _radius, bool *_ok) :
ParallelLoopBody(), src(_src), dst(_dst), sigma_color(_sigma_color), sigma_space(_sigma_space), radius(_radius), ok(_ok)
{
*ok = true;
}
virtual void operator() (const Range& range) const
{
int d = radius * 2 + 1;
IppiSize kernel = {d, d};
IppiSize roi={dst.cols, range.end - range.start};
int bufsize=0;
if (0 > ippiFilterBilateralGetBufSize_8u_C1R( ippiFilterBilateralGauss, roi, kernel, &bufsize))
{
*ok = false;
return;
}
AutoBuffer<uchar> buf(bufsize);
IppiFilterBilateralSpec *pSpec = (IppiFilterBilateralSpec *)alignPtr(&buf[0], 32);
if (0 > ippiFilterBilateralInit_8u_C1R( ippiFilterBilateralGauss, kernel, (Ipp32f)sigma_color, (Ipp32f)sigma_space, 1, pSpec ))
{
*ok = false;
return;
}
if (0 > ippiFilterBilateral_8u_C1R( src.ptr<uchar>(range.start) + radius * ((int)src.step[0] + 1), (int)src.step[0], dst.ptr<uchar>(range.start), (int)dst.step[0], roi, kernel, pSpec ))
*ok = false;
else
{
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
}
}
private:
Mat &src;
Mat &dst;
double sigma_color;
double sigma_space;
int radius;
bool *ok;
const IPPBilateralFilter_8u_Invoker& operator= (const IPPBilateralFilter_8u_Invoker&);
};
#endif
#ifdef HAVE_OPENCL
static bool ocl_bilateralFilter_8u(InputArray _src, OutputArray _dst, int d,
@@ -3861,24 +3788,6 @@ bilateralFilter_8u( const Mat& src, Mat& dst, int d,
Mat temp;
copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
#if defined HAVE_IPP && (IPP_VERSION_X100 >= 700) && IPP_DISABLE_BLOCK
CV_IPP_CHECK()
{
if( cn == 1 )
{
bool ok;
IPPBilateralFilter_8u_Invoker body(temp, dst, sigma_color * sigma_color, sigma_space * sigma_space, radius, &ok );
parallel_for_(Range(0, dst.rows), body, dst.total()/(double)(1<<16));
if( ok )
{
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
return;
}
setIppErrorStatus();
}
}
#endif
std::vector<float> _color_weight(cn*256);
std::vector<float> _space_weight(d*d);
std::vector<int> _space_ofs(d*d);
@@ -4293,6 +4202,107 @@ bilateralFilter_32f( const Mat& src, Mat& dst, int d,
parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16));
}
#ifdef HAVE_IPP
#define IPP_BILATERAL_PARALLEL 1
#ifdef HAVE_IPP_IW
class ipp_bilateralFilterParallel: public ParallelLoopBody
{
public:
ipp_bilateralFilterParallel(::ipp::IwiImage &_src, ::ipp::IwiImage &_dst, int _radius, Ipp32f _valSquareSigma, Ipp32f _posSquareSigma, ::ipp::IwiBorderType _borderType, bool *_ok):
src(_src), dst(_dst)
{
pOk = _ok;
radius = _radius;
valSquareSigma = _valSquareSigma;
posSquareSigma = _posSquareSigma;
borderType = _borderType;
*pOk = true;
}
~ipp_bilateralFilterParallel() {}
virtual void operator() (const Range& range) const
{
if(*pOk == false)
return;
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);
}
catch(::ipp::IwException)
{
*pOk = false;
return;
}
}
private:
::ipp::IwiImage &src;
::ipp::IwiImage &dst;
int radius;
Ipp32f valSquareSigma;
Ipp32f posSquareSigma;
::ipp::IwiBorderType borderType;
bool *pOk;
const ipp_bilateralFilterParallel& operator= (const ipp_bilateralFilterParallel&);
};
#endif
static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, double sigmaSpace, int borderType)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
int radius = IPP_MAX(((d <= 0)?cvRound(sigmaSpace*1.5):d/2), 1);
Ipp32f valSquareSigma = (Ipp32f)((sigmaColor <= 0)?1:sigmaColor*sigmaColor);
Ipp32f posSquareSigma = (Ipp32f)((sigmaSpace <= 0)?1:sigmaSpace*sigmaSpace);
// Acquire data and begin processing
try
{
::ipp::IwiImage iwSrc = ippiGetImage(src);
::ipp::IwiImage iwDst = ippiGetImage(dst);
::ipp::IwiBorderSize borderSize(radius);
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
if(!ippBorder.m_borderType)
return false;
// IW 2017u2 has bug which doesn't allow use of partial inMem with tiling
if((((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem))
return false;
bool ok = true;
int threads = ippiSuggestThreadsNum(iwDst, 2);
Range range(0, (int)iwDst.m_size.height);
ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok);
if(!ok)
return false;
if(IPP_BILATERAL_PARALLEL && threads > 1)
parallel_for_(range, invoker, threads*4);
else
invoker(range);
if(!ok)
return false;
}
catch (::ipp::IwException)
{
return false;
}
return true;
#else
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(d); CV_UNUSED(sigmaColor); CV_UNUSED(sigmaSpace); CV_UNUSED(borderType);
return false;
#endif
}
#endif
}
void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,
@@ -4308,6 +4318,8 @@ void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,
Mat src = _src.getMat(), dst = _dst.getMat();
CV_IPP_RUN_FAST(ipp_bilateralFilter(src, dst, d, sigmaColor, sigmaSpace, borderType));
if( src.depth() == CV_8U )
bilateralFilter_8u( src, dst, d, sigmaColor, sigmaSpace, borderType );
else if( src.depth() == CV_32F )
+31 -51
View File
@@ -405,58 +405,43 @@ static bool ipp_integral(
const uchar* src, size_t srcstep,
uchar* sum, size_t sumstep,
uchar* sqsum, size_t sqsumstep,
uchar* tilted, size_t tstep,
int width, int height, int cn)
{
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 != 900 // Disabled on ICV due invalid results
if( sdepth <= 0 )
sdepth = depth == CV_8U ? CV_32S : CV_64F;
if ( sqdepth <= 0 )
sqdepth = CV_64F;
sdepth = CV_MAT_DEPTH(sdepth), sqdepth = CV_MAT_DEPTH(sqdepth);
IppiSize size = {width, height};
if( ( depth == CV_8U ) && ( sdepth == CV_32F || sdepth == CV_32S ) && ( !sqsum || sqdepth == CV_64F ) && ( cn == 1 ) )
if(cn > 1)
return false;
if(tilted)
{
IppStatus status = ippStsErr;
IppiSize srcRoiSize = ippiSize( width, height );
if( sdepth == CV_32F )
{
if( sqsum )
{
status = CV_INSTRUMENT_FUN_IPP(ippiSqrIntegral_8u32f64f_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32f*)sum, (int)sumstep, (Ipp64f*)sqsum, (int)sqsumstep, srcRoiSize, 0, 0);
}
else
{
status = CV_INSTRUMENT_FUN_IPP(ippiIntegral_8u32f_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32f*)sum, (int)sumstep, srcRoiSize, 0);
}
}
else if( sdepth == CV_32S )
{
if( sqsum )
{
status = CV_INSTRUMENT_FUN_IPP(ippiSqrIntegral_8u32s64f_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32s*)sum, (int)sumstep, (Ipp64f*)sqsum, (int)sqsumstep, srcRoiSize, 0, 0);
}
else
{
status = CV_INSTRUMENT_FUN_IPP(ippiIntegral_8u32s_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32s*)sum, (int)sumstep, srcRoiSize, 0);
}
}
if (0 <= status)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
CV_UNUSED(tstep);
return false;
}
if(!sqsum)
{
if(depth == CV_8U && sdepth == CV_32S)
return CV_INSTRUMENT_FUN_IPP(ippiIntegral_8u32s_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32s*)sum, (int)sumstep, size, 0) >= 0;
else if(depth == CV_8UC1 && sdepth == CV_32F)
return CV_INSTRUMENT_FUN_IPP(ippiIntegral_8u32f_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32f*)sum, (int)sumstep, size, 0) >= 0;
else if(depth == CV_32FC1 && sdepth == CV_32F)
return CV_INSTRUMENT_FUN_IPP(ippiIntegral_32f_C1R, (const Ipp32f*)src, (int)srcstep, (Ipp32f*)sum, (int)sumstep, size) >= 0;
else
return false;
}
else
{
if(depth == CV_8U && sdepth == CV_32S && sqdepth == CV_32S)
return CV_INSTRUMENT_FUN_IPP(ippiSqrIntegral_8u32s_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32s*)sum, (int)sumstep, (Ipp32s*)sqsum, (int)sqsumstep, size, 0, 0) >= 0;
else if(depth == CV_8U && sdepth == CV_32S && sqdepth == CV_64F)
return CV_INSTRUMENT_FUN_IPP(ippiSqrIntegral_8u32s64f_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32s*)sum, (int)sumstep, (Ipp64f*)sqsum, (int)sqsumstep, size, 0, 0) >= 0;
else if(depth == CV_8U && sdepth == CV_32F && sqdepth == CV_64F)
return CV_INSTRUMENT_FUN_IPP(ippiSqrIntegral_8u32f64f_C1R, (const Ipp8u*)src, (int)srcstep, (Ipp32f*)sum, (int)sumstep, (Ipp64f*)sqsum, (int)sqsumstep, size, 0, 0) >= 0;
else
return false;
}
#else
CV_UNUSED(depth); CV_UNUSED(sdepth); CV_UNUSED(sqdepth);
CV_UNUSED(src); CV_UNUSED(srcstep);
CV_UNUSED(sum); CV_UNUSED(sumstep);
CV_UNUSED(sqsum); CV_UNUSED(sqsumstep);
CV_UNUSED(tilted); CV_UNUSED(tstep);
CV_UNUSED(width); CV_UNUSED(height); CV_UNUSED(cn);
#endif
return false;
}
}
#endif
@@ -471,12 +456,7 @@ void integral(int depth, int sdepth, int sqdepth,
int width, int height, int cn)
{
CALL_HAL(integral, cv_hal_integral, depth, sdepth, sqdepth, src, srcstep, sum, sumstep, sqsum, sqsumstep, tilted, tstep, width, height, cn);
CV_IPP_RUN(( depth == CV_8U )
&& ( sdepth == CV_32F || sdepth == CV_32S )
&& ( !tilted )
&& ( !sqsum || sqdepth == CV_64F )
&& ( cn == 1 ),
ipp_integral(depth, sdepth, sqdepth, src, srcstep, sum, sumstep, sqsum, sqsumstep, width, height, cn));
CV_IPP_RUN_FAST(ipp_integral(depth, sdepth, sqdepth, src, srcstep, sum, sumstep, sqsum, sqsumstep, tilted, tstep, width, height, cn));
#define ONE_CALL(A, B, C) integral_<A, B, C>((const A*)src, srcstep, (B*)sum, sumstep, (C*)sqsum, sqsumstep, (B*)tilted, tstep, width, height, cn)