added cv::Laplacian, cv::Sobel, cv::Scharr, cv::GaussianBlur to T-API

pull/1971/head
Ilya Lavrenov 11 years ago
parent d802b4d143
commit 8fa8b36b42
  1. 47
      modules/imgproc/src/deriv.cpp
  2. 44
      modules/imgproc/src/smooth.cpp
  3. 128
      modules/imgproc/test/ocl/test_filters.cpp
  4. 2
      modules/ts/include/opencv2/ts/ocl_test.hpp

@ -413,15 +413,15 @@ static bool IPPDeriv(const Mat& src, Mat& dst, int ddepth, int dx, int dy, int k
void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
int ksize, double scale, double delta, int borderType ) int ksize, double scale, double delta, int borderType )
{ {
Mat src = _src.getMat(); int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0) if (ddepth < 0)
ddepth = src.depth(); ddepth = sdepth;
_dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); _dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );
Mat dst = _dst.getMat();
#ifdef HAVE_TEGRA_OPTIMIZATION #ifdef HAVE_TEGRA_OPTIMIZATION
if (scale == 1.0 && delta == 0) if (scale == 1.0 && delta == 0)
{ {
Mat src = _src.getMat(), dst = _dst.getMat();
if (ksize == 3 && tegra::sobel3x3(src, dst, dx, dy, borderType)) if (ksize == 3 && tegra::sobel3x3(src, dst, dx, dy, borderType))
return; return;
if (ksize == -1 && tegra::scharr(src, dst, dx, dy, borderType)) if (ksize == -1 && tegra::scharr(src, dst, dx, dy, borderType))
@ -430,13 +430,14 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
#endif #endif
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
if(dx < 3 && dy < 3 && src.channels() == 1 && borderType == 1) if(dx < 3 && dy < 3 && cn == 1 && borderType == BORDER_REPLICATE)
{ {
Mat src = _src.getMat(), dst = _dst.getMat();
if(IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale)) if(IPPDeriv(src, dst, ddepth, dx, dy, ksize,scale))
return; return;
} }
#endif #endif
int ktype = std::max(CV_32F, std::max(ddepth, src.depth())); int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
Mat kx, ky; Mat kx, ky;
getDerivKernels( kx, ky, dx, dy, ksize, false, ktype ); getDerivKernels( kx, ky, dx, dy, ksize, false, ktype );
@ -449,33 +450,36 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
else else
ky *= scale; ky *= scale;
} }
sepFilter2D( src, dst, ddepth, kx, ky, Point(-1,-1), delta, borderType ); sepFilter2D( _src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType );
} }
void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
double scale, double delta, int borderType ) double scale, double delta, int borderType )
{ {
Mat src = _src.getMat(); int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0) if (ddepth < 0)
ddepth = src.depth(); ddepth = sdepth;
_dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); _dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );
Mat dst = _dst.getMat();
#ifdef HAVE_TEGRA_OPTIMIZATION #ifdef HAVE_TEGRA_OPTIMIZATION
if (scale == 1.0 && delta == 0) if (scale == 1.0 && delta == 0)
{
Mat src = _src.getMat(), dst = _dst.getMat();
if (tegra::scharr(src, dst, dx, dy, borderType)) if (tegra::scharr(src, dst, dx, dy, borderType))
return; return;
}
#endif #endif
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1) if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1)
{ {
Mat src = _src.getMat(), dst = _dst.getMat();
if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale)) if(IPPDerivScharr(src, dst, ddepth, dx, dy, scale))
return; return;
} }
#endif #endif
int ktype = std::max(CV_32F, std::max(ddepth, src.depth())); int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
Mat kx, ky; Mat kx, ky;
getScharrKernels( kx, ky, dx, dy, false, ktype ); getScharrKernels( kx, ky, dx, dy, false, ktype );
@ -488,22 +492,22 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
else else
ky *= scale; ky *= scale;
} }
sepFilter2D( src, dst, ddepth, kx, ky, Point(-1,-1), delta, borderType ); sepFilter2D( _src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType );
} }
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize, void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
double scale, double delta, int borderType ) double scale, double delta, int borderType )
{ {
Mat src = _src.getMat(); int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0) if (ddepth < 0)
ddepth = src.depth(); ddepth = sdepth;
_dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); _dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );
Mat dst = _dst.getMat();
#ifdef HAVE_TEGRA_OPTIMIZATION #ifdef HAVE_TEGRA_OPTIMIZATION
if (scale == 1.0 && delta == 0) if (scale == 1.0 && delta == 0)
{ {
Mat src = _src.getMat(), dst = _dst.getMat();
if (ksize == 1 && tegra::laplace1(src, dst, borderType)) if (ksize == 1 && tegra::laplace1(src, dst, borderType))
return; return;
if (ksize == 3 && tegra::laplace3(src, dst, borderType)) if (ksize == 3 && tegra::laplace3(src, dst, borderType))
@ -516,15 +520,18 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
if( ksize == 1 || ksize == 3 ) if( ksize == 1 || ksize == 3 )
{ {
float K[2][9] = float K[2][9] =
{{0, 1, 0, 1, -4, 1, 0, 1, 0}, {
{2, 0, 2, 0, -8, 0, 2, 0, 2}}; { 0, 1, 0, 1, -4, 1, 0, 1, 0 },
{ 2, 0, 2, 0, -8, 0, 2, 0, 2 }
};
Mat kernel(3, 3, CV_32F, K[ksize == 3]); Mat kernel(3, 3, CV_32F, K[ksize == 3]);
if( scale != 1 ) if( scale != 1 )
kernel *= scale; kernel *= scale;
filter2D( src, dst, ddepth, kernel, Point(-1,-1), delta, borderType ); filter2D( _src, _dst, ddepth, kernel, Point(-1, -1), delta, borderType );
} }
else else
{ {
Mat src = _src.getMat(), dst = _dst.getMat();
const size_t STRIPE_SIZE = 1 << 14; const size_t STRIPE_SIZE = 1 << 14;
int depth = src.depth(); int depth = src.depth();

@ -798,10 +798,10 @@ cv::Mat cv::getGaussianKernel( int n, double sigma, int ktype )
return kernel; return kernel;
} }
namespace cv {
cv::Ptr<cv::FilterEngine> cv::createGaussianFilter( int type, Size ksize, static void createGaussianKernels( Mat & kx, Mat & ky, int type, Size ksize,
double sigma1, double sigma2, double sigma1, double sigma2 )
int borderType )
{ {
int depth = CV_MAT_DEPTH(type); int depth = CV_MAT_DEPTH(type);
if( sigma2 <= 0 ) if( sigma2 <= 0 )
@ -819,12 +819,21 @@ cv::Ptr<cv::FilterEngine> cv::createGaussianFilter( int type, Size ksize,
sigma1 = std::max( sigma1, 0. ); sigma1 = std::max( sigma1, 0. );
sigma2 = std::max( sigma2, 0. ); sigma2 = std::max( sigma2, 0. );
Mat kx = getGaussianKernel( ksize.width, sigma1, std::max(depth, CV_32F) ); kx = getGaussianKernel( ksize.width, sigma1, std::max(depth, CV_32F) );
Mat ky;
if( ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON ) if( ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON )
ky = kx; ky = kx;
else else
ky = getGaussianKernel( ksize.height, sigma2, std::max(depth, CV_32F) ); ky = getGaussianKernel( ksize.height, sigma2, std::max(depth, CV_32F) );
}
}
cv::Ptr<cv::FilterEngine> cv::createGaussianFilter( int type, Size ksize,
double sigma1, double sigma2,
int borderType )
{
Mat kx, ky;
createGaussianKernels(kx, ky, type, ksize, sigma1, sigma2);
return createSeparableLinearFilter( type, type, kx, ky, Point(-1,-1), 0, borderType ); return createSeparableLinearFilter( type, type, kx, ky, Point(-1,-1), 0, borderType );
} }
@ -834,33 +843,34 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2, double sigma1, double sigma2,
int borderType ) int borderType )
{ {
Mat src = _src.getMat(); int type = _src.type();
_dst.create( src.size(), src.type() ); Size size = _src.size();
Mat dst = _dst.getMat(); _dst.create( size, type );
if( borderType != BORDER_CONSTANT ) if( borderType != BORDER_CONSTANT )
{ {
if( src.rows == 1 ) if( size.height == 1 )
ksize.height = 1; ksize.height = 1;
if( src.cols == 1 ) if( size.width == 1 )
ksize.width = 1; ksize.width = 1;
} }
if( ksize.width == 1 && ksize.height == 1 ) if( ksize.width == 1 && ksize.height == 1 )
{ {
src.copyTo(dst); _src.copyTo(_dst);
return; return;
} }
#ifdef HAVE_TEGRA_OPTIMIZATION #ifdef HAVE_TEGRA_OPTIMIZATION
if(sigma1 == 0 && sigma2 == 0 && tegra::gaussian(src, dst, ksize, borderType)) if(sigma1 == 0 && sigma2 == 0 && tegra::gaussian(_src.getMat(), _dst.getMat(), ksize, borderType))
return; return;
#endif #endif
#if defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7) #if defined HAVE_IPP && (IPP_VERSION_MAJOR >= 7)
if(src.type() == CV_32FC1 && sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 ) if( type == CV_32FC1 && sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 )
{ {
IppiSize roi = {src.cols, src.rows}; Mat src = _src.getMat(), dst = _dst.getMat();
IppiSize roi = { src.cols, src.rows };
int bufSize = 0; int bufSize = 0;
ippiFilterGaussGetBufferSize_32f_C1R(roi, ksize.width, &bufSize); ippiFilterGaussGetBufferSize_32f_C1R(roi, ksize.width, &bufSize);
AutoBuffer<uchar> buf(bufSize+128); AutoBuffer<uchar> buf(bufSize+128);
@ -873,11 +883,11 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
} }
#endif #endif
Ptr<FilterEngine> f = createGaussianFilter( src.type(), ksize, sigma1, sigma2, borderType ); Mat kx, ky;
f->apply( src, dst ); createGaussianKernels(kx, ky, type, ksize, sigma1, sigma2);
sepFilter2D(_src, _dst, CV_MAT_DEPTH(type), kx, ky, Point(-1,-1), 0, borderType );
} }
/****************************************************************************************\ /****************************************************************************************\
Median Filter Median Filter
\****************************************************************************************/ \****************************************************************************************/

@ -60,7 +60,7 @@ namespace ocl {
PARAM_TEST_CASE(FilterTestBase, MatType, PARAM_TEST_CASE(FilterTestBase, MatType,
int, // kernel size int, // kernel size
Size, // dx, dy Size, // dx, dy
int, // border type BorderType, // border type
double, // optional parameter double, // optional parameter
bool) // roi or not bool) // roi or not
{ {
@ -145,32 +145,146 @@ OCL_TEST_P(Bilateral, Mat)
} }
} }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Laplacian
typedef FilterTestBase LaplacianTest;
OCL_TEST_P(LaplacianTest, Accuracy)
{
double scale = param;
for (int j = 0; j < test_loop_times; j++)
{
random_roi();
OCL_OFF(cv::Laplacian(src_roi, dst_roi, -1, ksize, scale, 0, borderType));
OCL_ON(cv::Laplacian(usrc_roi, udst_roi, -1, ksize, scale, 0, borderType));
Near();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Sobel
typedef FilterTestBase SobelTest;
OCL_TEST_P(SobelTest, Mat)
{
int dx = size.width, dy = size.height;
double scale = param;
for (int j = 0; j < test_loop_times; j++)
{
random_roi();
OCL_OFF(cv::Sobel(src_roi, dst_roi, -1, dx, dy, ksize, scale, /* delta */0, borderType));
OCL_ON(cv::Sobel(usrc_roi, udst_roi, -1, dx, dy, ksize, scale, /* delta */0, borderType));
Near();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Scharr
typedef FilterTestBase ScharrTest;
OCL_TEST_P(ScharrTest, Mat)
{
int dx = size.width, dy = size.height;
double scale = param;
for (int j = 0; j < test_loop_times; j++)
{
random_roi();
OCL_OFF(cv::Scharr(src_roi, dst_roi, -1, dx, dy, scale, /* delta */ 0, borderType));
OCL_ON(cv::Scharr(usrc_roi, udst_roi, -1, dx, dy, scale, /* delta */ 0, borderType));
Near();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// GaussianBlur
typedef FilterTestBase GaussianBlurTest;
OCL_TEST_P(GaussianBlurTest, Mat)
{
for (int j = 0; j < test_loop_times; j++)
{
random_roi();
double sigma1 = rng.uniform(0.1, 1.0);
double sigma2 = rng.uniform(0.1, 1.0);
OCL_OFF(cv::GaussianBlur(src_roi, dst_roi, Size(ksize, ksize), sigma1, sigma2, borderType));
OCL_ON(cv::GaussianBlur(usrc_roi, udst_roi, Size(ksize, ksize), sigma1, sigma2, borderType));
Near(CV_MAT_DEPTH(type) == CV_8U ? 3 : 5e-5, false);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define FILTER_BORDER_SET_NO_ISOLATED \ #define FILTER_BORDER_SET_NO_ISOLATED \
Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, (int)BORDER_REFLECT, (int)BORDER_WRAP, (int)BORDER_REFLECT_101/*, \ Values((BorderType)BORDER_CONSTANT, (BorderType)BORDER_REPLICATE, (BorderType)BORDER_REFLECT, (BorderType)BORDER_WRAP, (BorderType)BORDER_REFLECT_101/*, \
(int)BORDER_CONSTANT|BORDER_ISOLATED, (int)BORDER_REPLICATE|BORDER_ISOLATED, \ (int)BORDER_CONSTANT|BORDER_ISOLATED, (int)BORDER_REPLICATE|BORDER_ISOLATED, \
(int)BORDER_REFLECT|BORDER_ISOLATED, (int)BORDER_WRAP|BORDER_ISOLATED, \ (int)BORDER_REFLECT|BORDER_ISOLATED, (int)BORDER_WRAP|BORDER_ISOLATED, \
(int)BORDER_REFLECT_101|BORDER_ISOLATED*/) // WRAP and ISOLATED are not supported by cv:: version (int)BORDER_REFLECT_101|BORDER_ISOLATED*/) // WRAP and ISOLATED are not supported by cv:: version
#define FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED \ #define FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED \
Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, (int)BORDER_REFLECT, /*(int)BORDER_WRAP,*/ (int)BORDER_REFLECT_101/*, \ Values((BorderType)BORDER_CONSTANT, (BorderType)BORDER_REPLICATE, (BorderType)BORDER_REFLECT, /*(int)BORDER_WRAP,*/ (BorderType)BORDER_REFLECT_101/*, \
(int)BORDER_CONSTANT|BORDER_ISOLATED, (int)BORDER_REPLICATE|BORDER_ISOLATED, \ (int)BORDER_CONSTANT|BORDER_ISOLATED, (int)BORDER_REPLICATE|BORDER_ISOLATED, \
(int)BORDER_REFLECT|BORDER_ISOLATED, (int)BORDER_WRAP|BORDER_ISOLATED, \ (int)BORDER_REFLECT|BORDER_ISOLATED, (int)BORDER_WRAP|BORDER_ISOLATED, \
(int)BORDER_REFLECT_101|BORDER_ISOLATED*/) // WRAP and ISOLATED are not supported by cv:: version (int)BORDER_REFLECT_101|BORDER_ISOLATED*/) // WRAP and ISOLATED are not supported by cv:: version
#define FILTER_DATATYPES Values(CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4, \ #define FILTER_TYPES Values(CV_8UC1, CV_8UC2, CV_8UC4, CV_32FC1, CV_32FC4, CV_64FC1, CV_64FC4)
CV_32FC1, CV_32FC3, CV_32FC4, \
CV_64FC1, CV_64FC3, CV_64FC4)
OCL_INSTANTIATE_TEST_CASE_P(Filter, Bilateral, Combine( OCL_INSTANTIATE_TEST_CASE_P(Filter, Bilateral, Combine(
Values((MatType)CV_8UC1), Values((MatType)CV_8UC1),
Values(5, 9), Values(5, 9), // kernel size
Values(Size(0, 0)), // not used Values(Size(0, 0)), // not used
FILTER_BORDER_SET_NO_ISOLATED, FILTER_BORDER_SET_NO_ISOLATED,
Values(0.0), // not used Values(0.0), // not used
Bool())); Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Filter, LaplacianTest, Combine(
FILTER_TYPES,
Values(1, 3), // kernel size
Values(Size(0, 0)), // not used
FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED,
Values(1.0, 0.2, 3.0), // kernel scale
Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Filter, SobelTest, Combine(
FILTER_TYPES,
Values(3, 5), // kernel size
Values(Size(1, 0), Size(1, 1), Size(2, 0), Size(2, 1)), // dx, dy
FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED,
Values(0.0), // not used
Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Filter, ScharrTest, Combine(
FILTER_TYPES,
Values(0), // not used
Values(Size(0, 1), Size(1, 0)), // dx, dy
FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED,
Values(1.0, 0.2), // kernel scale
Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Filter, GaussianBlurTest, Combine(
FILTER_TYPES,
Values(3, 5), // kernel size
Values(Size(0, 0)), // not used
FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED,
Values(0.0), // not used
Bool()));
} } // namespace cvtest::ocl } } // namespace cvtest::ocl
#endif // HAVE_OPENCL #endif // HAVE_OPENCL

@ -307,7 +307,7 @@ IMPLEMENT_PARAM_CLASS(Channels, int)
CV_ENUM(Interpolation, INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_AREA) CV_ENUM(Interpolation, INTER_NEAREST, INTER_LINEAR, INTER_CUBIC, INTER_AREA)
CV_ENUM(ThreshOp, THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV) CV_ENUM(ThreshOp, THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV)
CV_ENUM(BorderType, BORDER_REPLICATE, BORDER_REFLECT, BORDER_WRAP, BORDER_REFLECT_101) CV_ENUM(BorderType, BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT, BORDER_WRAP, BORDER_REFLECT_101)
#define OCL_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ #define OCL_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
INSTANTIATE_TEST_CASE_P(OCL_ ## prefix, test_case_name, generator) INSTANTIATE_TEST_CASE_P(OCL_ ## prefix, test_case_name, generator)

Loading…
Cancel
Save