added IPP Sobel and Sharr filters. Also some minor changes.
This commit is contained in:
parent
d3462dfcba
commit
c987b9f180
@ -268,6 +268,16 @@ typedef NoVec VXor8u;
|
|||||||
|
|
||||||
|
|
||||||
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||||
|
struct IPPArithmInitializer
|
||||||
|
{
|
||||||
|
IPPArithmInitializer(void)
|
||||||
|
{
|
||||||
|
IppStatus status = ippStaticInit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IPPArithmInitializer ippArithmInitializer;
|
||||||
|
|
||||||
struct ippAdd8u
|
struct ippAdd8u
|
||||||
{
|
{
|
||||||
int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
|
int operator()(const Ipp8u* src1, const Ipp8u* src2, Ipp8u* dst, int len) const
|
||||||
|
@ -40,7 +40,9 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||||
|
static IppStatus sts = ippInit();
|
||||||
|
#endif
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
|
|
||||||
/* lightweight convolution with 3x3 kernel */
|
/* 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,
|
void Sobel( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
|
||||||
int ksize, double scale, double delta, int borderType )
|
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()));
|
int ktype = std::max(CV_32F, std::max(ddepth, src.depth()));
|
||||||
|
|
||||||
Mat kx, ky;
|
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,
|
void Scharr( const Mat& src, Mat& dst, int ddepth, int dx, int dy,
|
||||||
double scale, double delta, int borderType )
|
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()));
|
int ktype = std::max(CV_32F, std::max(ddepth, src.depth()));
|
||||||
|
|
||||||
Mat kx, ky;
|
Mat kx, ky;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user