added IPP Sobel and Sharr filters. Also some minor changes.

pull/13383/head
Vladimir Dudnik 14 years ago
parent d3462dfcba
commit c987b9f180
  1. 2
      modules/core/include/opencv2/core/mat.hpp
  2. 10
      modules/core/src/arithm.cpp
  3. 247
      modules/imgproc/src/deriv.cpp

@ -168,7 +168,7 @@ inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
dataend = datalimit - _step + minstep;
}
inline Mat::Mat(const CvMat* m, bool copyData)
: flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
dims(2), rows(m->rows), cols(m->cols), data(m->data.ptr), refcount(0),

@ -268,6 +268,16 @@ typedef NoVec VXor8u;
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
struct IPPArithmInitializer
{
IPPArithmInitializer(void)
{
IppStatus status = ippStaticInit();
}
};
IPPArithmInitializer ippArithmInitializer;
struct ippAdd8u
{
int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const

@ -40,7 +40,9 @@
//M*/
#include "precomp.hpp"
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
static IppStatus sts = ippInit();
#endif
/****************************************************************************************/
/* lightweight convolution with 3x3 kernel */
@ -237,9 +239,245 @@ Ptr<FilterEngine> createDerivFilter(int srcType, int dstType,
}
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
static bool IPPDerivScharr(const Mat& src, Mat& dst, int ddepth, int dx, int dy, double scale)
{
int bufSize = 0;
cv::AutoBuffer<char> buffer;
IppiSize roi = ippiSize(src.cols, src.rows);
if( ddepth < 0 )
ddepth = src.depth();
dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
switch(src.type())
{
case CV_8U:
{
if(scale != 1)
return false;
switch(dst.type())
{
case CV_16S:
{
if((dx == 1) && (dy == 0))
{
ippiFilterScharrVertGetBufferSize_8u16s_C1R(roi,&bufSize);
buffer.allocate(bufSize);
ippiFilterScharrVertBorder_8u16s_C1R((const Ipp8u*)src.data, src.step,
(Ipp16s*)dst.data, dst.step, roi, ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
return true;
}
if((dx == 0) && (dy == 1))
{
ippiFilterScharrHorizGetBufferSize_8u16s_C1R(roi,&bufSize);
buffer.allocate(bufSize);
ippiFilterScharrHorizBorder_8u16s_C1R((const Ipp8u*)src.data, src.step,
(Ipp16s*)dst.data, dst.step, roi, ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
return true;
}
}
default:
return false;
}
}
case CV_32F:
{
switch(dst.type())
{
case CV_32F:
if((dx == 1) && (dy == 0))
{
ippiFilterScharrVertGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows),&bufSize);
buffer.allocate(bufSize);
ippiFilterScharrVertBorder_32f_C1R((const Ipp32f*)src.data, src.step,
(Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
if(scale != 1)
/* IPP is fast, so MulC produce very little perf degradation */
ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f*)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows));
return true;
}
if((dx == 0) && (dy == 1))
{
ippiFilterScharrHorizGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows),&bufSize);
buffer.allocate(bufSize);
ippiFilterScharrHorizBorder_32f_C1R((const Ipp32f*)src.data, src.step,
(Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
if(scale != 1)
ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows));
return true;
}
default:
return false;
}
}
default:
return false;
}
}
static bool IPPDeriv(const Mat& src, Mat& dst, int ddepth, int dx, int dy, int ksize, double scale)
{
int bufSize = 0;
cv::AutoBuffer<char> buffer;
if(ksize == 3 || ksize == 5)
{
if( ddepth < 0 )
ddepth = src.depth();
dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
if(src.type() == CV_8U && dst.type() == CV_16S && scale == 1)
{
if((dx == 1) && (dy == 0))
{
ippiFilterSobelNegVertGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelNegVertBorder_8u16s_C1R((const Ipp8u*)src.data, src.step,
(Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
return true;
}
if((dx == 0) && (dy == 1))
{
ippiFilterSobelHorizGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelHorizBorder_8u16s_C1R((const Ipp8u*)src.data, src.step,
(Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
return true;
}
if((dx == 2) && (dy == 0))
{
ippiFilterSobelVertSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelVertSecondBorder_8u16s_C1R((const Ipp8u*)src.data, src.step,
(Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
return true;
}
if((dx == 0) && (dy == 2))
{
ippiFilterSobelHorizSecondGetBufferSize_8u16s_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelHorizSecondBorder_8u16s_C1R((const Ipp8u*)src.data, src.step,
(Ipp16s*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
return true;
}
}
if(src.type() == CV_32F && dst.type() == CV_32F)
{
if((dx == 1) && (dy == 0))
{
ippiFilterSobelNegVertGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelNegVertBorder_32f_C1R((const Ipp32f*)src.data, src.step,
(Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
if(scale != 1)
ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows));
return true;
}
if((dx == 0) && (dy == 1))
{
ippiFilterSobelHorizGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelHorizBorder_32f_C1R((const Ipp32f*)src.data, src.step,
(Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
if(scale != 1)
ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows));
return true;
}
if((dx == 2) && (dy == 0))
{
ippiFilterSobelVertSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelVertSecondBorder_32f_C1R((const Ipp32f*)src.data, src.step,
(Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
if(scale != 1)
ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows));
return true;
}
if((dx == 0) && (dy == 2))
{
ippiFilterSobelHorizSecondGetBufferSize_32f_C1R(ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),&bufSize);
buffer.allocate(bufSize);
ippiFilterSobelHorizSecondBorder_32f_C1R((const Ipp32f*)src.data, src.step,
(Ipp32f*)dst.data, dst.step, ippiSize(src.cols, src.rows), (IppiMaskSize)(ksize*10+ksize),
ippBorderRepl, 0, (Ipp8u*)(char*)buffer);
if(scale != 1)
ippiMulC_32f_C1IR((Ipp32f)scale,(Ipp32f *)dst.data,dst.step,ippiSize(dst.cols*dst.channels(),dst.rows));
return true;
}
}
}
if(ksize <= 0)
return IPPDerivScharr(src, dst, ddepth, dx, dy, scale);
return false;
}
#endif
void Sobel( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
int ksize, double scale, double delta, int borderType )
{
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
if(dx < 3 && dy < 3 && src.channels() == 1 && borderType == 1)
{
if(IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale) == true)
return;
}
#endif
int ktype = std::max(CV_32F, std::max(ddepth, src.depth()));
Mat kx, ky;
@ -260,6 +498,13 @@ void Sobel( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
void Scharr( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
double scale, double delta, int borderType )
{
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1)
{
if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale) == true)
return;
}
#endif
int ktype = std::max(CV_32F, std::max(ddepth, src.depth()));
Mat kx, ky;

Loading…
Cancel
Save