From 2f1cd91ff3443d7db99632d902eb411433986518 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 3 Nov 2011 16:08:49 +0000 Subject: [PATCH] More performance tests for Sobel and Scharr filters --- modules/imgproc/perf/perf_filters.cpp | 233 ++++++++++++++++++++++++-- modules/imgproc/src/deriv.cpp | 16 ++ 2 files changed, 236 insertions(+), 13 deletions(-) diff --git a/modules/imgproc/perf/perf_filters.cpp b/modules/imgproc/perf/perf_filters.cpp index 74eebd09f2..78217ad227 100644 --- a/modules/imgproc/perf/perf_filters.cpp +++ b/modules/imgproc/perf/perf_filters.cpp @@ -7,32 +7,239 @@ using namespace perf; using std::tr1::make_tuple; using std::tr1::get; -CV_ENUM(SobelBorderType, BORDER_CONSTANT, BORDER_REFLECT, BORDER_REFLECT_101) +#define FILTER_SRC_SIZES szODD, szQVGA, szVGA -typedef std::tr1::tuple, int, SobelBorderType> Size_dx_dy_kernel_Border_t; -typedef perf::TestBaseWithParam Size_dx_dy_kernel_Border; +CV_ENUM(BorderType3x3, BORDER_REPLICATE, BORDER_CONSTANT) +CV_ENUM(BorderType3x3ROI, BORDER_DEFAULT, BORDER_REPLICATE|BORDER_ISOLATED, BORDER_CONSTANT|BORDER_ISOLATED) -PERF_TEST_P(Size_dx_dy_kernel_Border, sobel, +CV_ENUM(BorderType, BORDER_REPLICATE, BORDER_CONSTANT, BORDER_REFLECT, BORDER_REFLECT101) +CV_ENUM(BorderTypeROI, BORDER_DEFAULT, BORDER_REPLICATE|BORDER_ISOLATED, BORDER_CONSTANT|BORDER_ISOLATED, BORDER_REFLECT|BORDER_ISOLATED, BORDER_REFLECT101|BORDER_ISOLATED) + +typedef std::tr1::tuple, BorderType3x3> Size_MatType_dx_dy_Border3x3_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border3x3; + +typedef std::tr1::tuple, BorderType3x3ROI> Size_MatType_dx_dy_Border3x3ROI_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border3x3ROI; + +typedef std::tr1::tuple, BorderType> Size_MatType_dx_dy_Border5x5_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border5x5; + +typedef std::tr1::tuple, BorderTypeROI> Size_MatType_dx_dy_Border5x5ROI_t; +typedef perf::TestBaseWithParam Size_MatType_dx_dy_Border5x5ROI; + + +/**************** Sobel ********************/ + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3, sobelFilter, testing::Combine( - testing::Values(szVGA, szQVGA), + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0), make_tuple(2, 2)), - testing::Values(3, 5), - testing::ValuesIn(SobelBorderType::all()) + testing::ValuesIn(BorderType3x3::all()) ) ) { Size size = get<0>(GetParam()); - int dx = get<0>(get<1>(GetParam())); - int dy = get<1>(get<1>(GetParam())); - int ksize = get<2>(GetParam()); - SobelBorderType border = get<3>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3 border = get<3>(GetParam()); Mat src(size, CV_8U); - Mat dst(size, CV_32F); + Mat dst(size, ddepth); declare.in(src, WARMUP_RNG).out(dst); - TEST_CYCLE(100) { Sobel(src, dst, CV_32F, dx, dy, ksize, 1, 0, border); } + TEST_CYCLE(100) { Sobel(src, dst, ddepth, dx, dy, 3, 1, 0, border); } + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3ROI, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0), make_tuple(2, 2)), + testing::ValuesIn(BorderType3x3ROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3ROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE(100) { Sobel(src, dst, ddepth, dx, dy, 3, 1, 0, border); } + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border5x5, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0)), + testing::ValuesIn(BorderType::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE(100) { Sobel(src, dst, ddepth, dx, dy, 5, 1, 0, border); } + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border5x5ROI, sobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0), make_tuple(1, 1), make_tuple(0, 2), make_tuple(2, 0)), + testing::ValuesIn(BorderTypeROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderTypeROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE(100) { Sobel(src, dst, ddepth, dx, dy, 5, 1, 0, border); } + + SANITY_CHECK(dst); +} + +/**************** Scharr ********************/ + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3, scharrFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3 border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE(100) { Scharr(src, dst, ddepth, dx, dy, 1, 0, border); } + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3ROI, scharrFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3ROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3ROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE(100) { Scharr(src, dst, ddepth, dx, dy, 1, 0, border); } + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3, scharrViaSobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3 border = get<3>(GetParam()); + + Mat src(size, CV_8U); + Mat dst(size, ddepth); + + declare.in(src, WARMUP_RNG).out(dst); + + TEST_CYCLE(100) { Sobel(src, dst, ddepth, dx, dy, -1, 1, 0, border); } + + SANITY_CHECK(dst); +} + +PERF_TEST_P(Size_MatType_dx_dy_Border3x3ROI, scharrViaSobelFilter, + testing::Combine( + testing::Values(FILTER_SRC_SIZES), + testing::Values(CV_16S, CV_32F), + testing::Values(make_tuple(0, 1), make_tuple(1, 0)), + testing::ValuesIn(BorderType3x3ROI::all()) + ) + ) +{ + Size size = get<0>(GetParam()); + int ddepth = get<1>(GetParam()); + int dx = get<0>(get<2>(GetParam())); + int dy = get<1>(get<2>(GetParam())); + BorderType3x3ROI border = get<3>(GetParam()); + + Mat src(size.height + 10, size.width + 10, CV_8U); + Mat dst(size, ddepth); + + warmup(src, WARMUP_RNG); + src = src(Range(5, 5 + size.height), Range(5, 5 + size.width)); + + declare.in(src).out(dst); + + TEST_CYCLE(100) { Sobel(src, dst, ddepth, dx, dy, -1, 1, 0, border); } SANITY_CHECK(dst); } diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index d38e76e563..8703cf7cd5 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -478,6 +478,16 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, ddepth = src.depth(); _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (scale == 1.0 && delta == 0) + { + if (ksize == 3 && tegra::sobel3x3(src, dst, dx, dy, borderType)) + return; + if (ksize == -1 && tegra::scharr(src, dst, dx, dy, borderType)) + return; + } +#endif #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) if(dx < 3 && dy < 3 && src.channels() == 1 && borderType == 1) @@ -511,6 +521,12 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, ddepth = src.depth(); _dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) ); Mat dst = _dst.getMat(); + +#ifdef HAVE_TEGRA_OPTIMIZATION + if (scale == 1.0 && delta == 0) + if (tegra::scharr(src, dst, dx, dy, borderType)) + return; +#endif #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) if(dx < 2 && dy < 2 && src.channels() == 1 && borderType == 1)