From cb6ea8bfa1dffe39afe820082727c5b2591f3890 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Sat, 26 Oct 2013 11:37:02 +0400 Subject: [PATCH] ocl: update filter tests --- modules/ocl/test/test_filters.cpp | 235 ++++++++++++++++++++------------------ modules/ocl/test/utility.hpp | 14 +++ 2 files changed, 140 insertions(+), 109 deletions(-) diff --git a/modules/ocl/test/test_filters.cpp b/modules/ocl/test/test_filters.cpp index 86ff834..3cf7d37 100644 --- a/modules/ocl/test/test_filters.cpp +++ b/modules/ocl/test/test_filters.cpp @@ -59,10 +59,15 @@ using namespace cv; PARAM_TEST_CASE(FilterTestBase, MatType, int, // kernel size Size, // dx, dy - int, // border type, or iteration + int, // border type + double, // optional parameter bool) // roi or not { + bool isFP; + int type, borderType, ksize; + Size size; + double param; bool useRoi; Mat src, dst_whole, src_roi, dst_roi; @@ -72,31 +77,53 @@ PARAM_TEST_CASE(FilterTestBase, MatType, { type = GET_PARAM(0); ksize = GET_PARAM(1); + size = GET_PARAM(2); borderType = GET_PARAM(3); - useRoi = GET_PARAM(4); + param = GET_PARAM(4); + useRoi = GET_PARAM(5); + + isFP = (CV_MAT_DEPTH(type) == CV_32F || CV_MAT_DEPTH(type) == CV_64F); } - void random_roi() + void random_roi(int minSize = 1) { - Size roiSize = randomSize(1, MAX_VALUE); + if (minSize == 0) + minSize = ksize; + Size roiSize = randomSize(minSize, MAX_VALUE); Border srcBorder = randomBorder(0, useRoi ? MAX_VALUE : 0); - randomSubMat(src, src_roi, roiSize, srcBorder, type, 5, 256); + randomSubMat(src, src_roi, roiSize, srcBorder, type, isFP ? 0 : 5, isFP ? 1 : 256); Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0); - randomSubMat(dst_whole, dst_roi, roiSize, dstBorder, type, 5, 16); + randomSubMat(dst_whole, dst_roi, roiSize, dstBorder, type, isFP ? 0.20 : 60, isFP ? 0.25 : 70); generateOclMat(gsrc_whole, gsrc_roi, src, roiSize, srcBorder); generateOclMat(gdst_whole, gdst_roi, dst_whole, roiSize, dstBorder); } - void Near(double threshold = 0.0) + void Near() + { + if (isFP) + Near(1e-6, true); + else + Near(1, false); + } + + void Near(double threshold, bool relative) { Mat roi, whole; gdst_whole.download(whole); gdst_roi.download(roi); - EXPECT_MAT_NEAR(dst_whole, whole, threshold); - EXPECT_MAT_NEAR(dst_roi, roi, threshold); + if (relative) + { + EXPECT_MAT_NEAR_RELATIVE(dst_whole, whole, threshold); + EXPECT_MAT_NEAR_RELATIVE(dst_roi, roi, threshold); + } + else + { + EXPECT_MAT_NEAR(dst_whole, whole, threshold); + EXPECT_MAT_NEAR(dst_roi, roi, threshold); + } } }; @@ -111,12 +138,12 @@ OCL_TEST_P(Blur, Mat) for (int j = 0; j < LOOP_TIMES; j++) { - random_roi(); + random_roi(0); // TODO NOTE: min value for size is kernel size (temporary bypass border issues in CPU implementation) blur(src_roi, dst_roi, kernelSize, Point(-1, -1), borderType); ocl::blur(gsrc_roi, gdst_roi, kernelSize, Point(-1, -1), borderType); // TODO anchor - Near(1.0); + Near(); } } @@ -127,64 +154,51 @@ typedef FilterTestBase LaplacianTest; OCL_TEST_P(LaplacianTest, Accuracy) { + double scale = param; + for (int j = 0; j < LOOP_TIMES; j++) { random_roi(); - // border type is used as a scale factor for the Laplacian kernel - double scale = static_cast(borderType); - - Laplacian(src_roi, dst_roi, -1, ksize, scale); - ocl::Laplacian(gsrc_roi, gdst_roi, -1, ksize, scale); + Laplacian(src_roi, dst_roi, -1, ksize, scale); // TODO FIXIT , 0, borderType); + ocl::Laplacian(gsrc_roi, gdst_roi, -1, ksize, scale); // TODO FIXIT , 0, borderType); - Near(1e-5); + Near(); } } ///////////////////////////////////////////////////////////////////////////////////////////////// // erode & dilate -struct ErodeDilate : - public FilterTestBase -{ - int iterations; - - virtual void SetUp() - { - type = GET_PARAM(0); - ksize = GET_PARAM(1); - iterations = GET_PARAM(3); - useRoi = GET_PARAM(4); - } -}; - -typedef ErodeDilate Erode; +typedef FilterTestBase Erode; OCL_TEST_P(Erode, Mat) { // erode or dilate kernel Size kernelSize(ksize, ksize); Mat kernel; + int iterations = (int)param; for (int j = 0; j < LOOP_TIMES; j++) { - kernel = randomMat(kernelSize, CV_8UC1, 0, 3); - random_roi(); - cv::erode(src_roi, dst_roi, kernel, Point(-1, -1), iterations); - ocl::erode(gsrc_roi, gdst_roi, kernel, Point(-1, -1), iterations); // TODO iterations, borderType + kernel = randomMat(kernelSize, CV_8UC1, 0, 3); - Near(1e-5); + cv::erode(src_roi, dst_roi, kernel, Point(-1, -1), iterations);//, borderType); + ocl::erode(gsrc_roi, gdst_roi, kernel, Point(-1, -1), iterations);//, borderType); + + Near(); } } -typedef ErodeDilate Dilate; +typedef FilterTestBase Dilate; OCL_TEST_P(Dilate, Mat) { // erode or dilate kernel Mat kernel; + int iterations = (int)param; for (int j = 0; j < LOOP_TIMES; j++) { @@ -195,79 +209,56 @@ OCL_TEST_P(Dilate, Mat) cv::dilate(src_roi, dst_roi, kernel, Point(-1, -1), iterations); ocl::dilate(gsrc_roi, gdst_roi, kernel, Point(-1, -1), iterations); // TODO iterations, borderType - Near(1e-5); + Near(); } } ///////////////////////////////////////////////////////////////////////////////////////////////// // Sobel -struct SobelTest : - public FilterTestBase -{ - int dx, dy; - - virtual void SetUp() - { - type = GET_PARAM(0); - ksize = GET_PARAM(1); - borderType = GET_PARAM(3); - useRoi = GET_PARAM(4); - - Size d = GET_PARAM(2); - dx = d.width, dy = d.height; - } -}; +typedef FilterTestBase SobelTest; OCL_TEST_P(SobelTest, Mat) { + int dx = size.width, dy = size.height; + double scale = param; + for (int j = 0; j < LOOP_TIMES; j++) { random_roi(); - Sobel(src_roi, dst_roi, -1, dx, dy, ksize, /* scale */ 0.00001, /* delta */0, borderType); - ocl::Sobel(gsrc_roi, gdst_roi, -1, dx, dy, ksize, /* scale */ 0.00001, /* delta */ 0, borderType); + Sobel(src_roi, dst_roi, -1, dx, dy, ksize, scale, /* delta */0, borderType); + ocl::Sobel(gsrc_roi, gdst_roi, -1, dx, dy, ksize, scale, /* delta */0, borderType); - Near(1); + Near(); } } ///////////////////////////////////////////////////////////////////////////////////////////////// // Scharr -typedef SobelTest ScharrTest; +typedef FilterTestBase ScharrTest; OCL_TEST_P(ScharrTest, Mat) { + int dx = size.width, dy = size.height; + double scale = param; + for (int j = 0; j < LOOP_TIMES; j++) { random_roi(); - Scharr(src_roi, dst_roi, -1, dx, dy, /* scale */ 1, /* delta */ 0, borderType); - ocl::Scharr(gsrc_roi, gdst_roi, -1, dx, dy, /* scale */ 1, /* delta */ 0, borderType); + Scharr(src_roi, dst_roi, -1, dx, dy, scale, /* delta */ 0, borderType); + ocl::Scharr(gsrc_roi, gdst_roi, -1, dx, dy, scale, /* delta */ 0, borderType); - Near(1); + Near(); } } ///////////////////////////////////////////////////////////////////////////////////////////////// // GaussianBlur -struct GaussianBlurTest : - public FilterTestBase -{ - double sigma1, sigma2; - - virtual void SetUp() - { - type = GET_PARAM(0); - ksize = GET_PARAM(1); - borderType = GET_PARAM(3); - - sigma1 = rng.uniform(0.1, 1.0); - sigma2 = rng.uniform(0.1, 1.0); - } -}; +typedef FilterTestBase GaussianBlurTest; OCL_TEST_P(GaussianBlurTest, Mat) { @@ -275,10 +266,13 @@ OCL_TEST_P(GaussianBlurTest, Mat) { random_roi(); + double sigma1 = rng.uniform(0.1, 1.0); + double sigma2 = rng.uniform(0.1, 1.0); + GaussianBlur(src_roi, dst_roi, Size(ksize, ksize), sigma1, sigma2, borderType); ocl::GaussianBlur(gsrc_roi, gdst_roi, Size(ksize, ksize), sigma1, sigma2, borderType); - Near(1); + Near(); } } @@ -289,19 +283,24 @@ typedef FilterTestBase Filter2D; OCL_TEST_P(Filter2D, Mat) { - const Size kernelSize(ksize, ksize); - Mat kernel; - for (int j = 0; j < LOOP_TIMES; j++) { - kernel = randomMat(kernelSize, CV_32FC1, 0.0, 1.0); - random_roi(); - cv::filter2D(src_roi, dst_roi, -1, kernel, Point(-1, -1), 0.0, borderType); // TODO anchor - ocl::filter2D(gsrc_roi, gdst_roi, -1, kernel, Point(-1, -1), borderType); + Point anchor(-1, -1); + if (size.width >= 0) + anchor.x = size.width % ksize; + if (size.height >= 0) + anchor.y = size.height % ksize; - Near(1); + const Size kernelSize(ksize, ksize); + Mat kernel = randomMat(kernelSize, CV_32FC1, 0, 1.0); + kernel *= 1.0 / (double)(ksize * ksize); + + cv::filter2D(src_roi, dst_roi, -1, kernel, anchor, 0.0, borderType); + ocl::filter2D(gsrc_roi, gdst_roi, -1, kernel, anchor, /* TODO FIXIT 0.0,*/ borderType); + + Near(); } } @@ -322,7 +321,7 @@ OCL_TEST_P(Bilateral, Mat) cv::bilateralFilter(src_roi, dst_roi, ksize, sigmacolor, sigmaspace, borderType); ocl::bilateralFilter(gsrc_roi, gdst_roi, ksize, sigmacolor, sigmaspace, borderType); - Near(1); + Near(); } } @@ -342,7 +341,7 @@ OCL_TEST_P(AdaptiveBilateral, Mat) adaptiveBilateralFilter(src_roi, dst_roi, kernelSize, 5, Point(-1, -1), borderType); // TODO anchor ocl::adaptiveBilateralFilter(gsrc_roi, gdst_roi, kernelSize, 5, Point(-1, -1), borderType); - Near(1); + Near(); } } @@ -366,80 +365,97 @@ OCL_TEST_P(MedianFilter, Mat) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define FILTER_BORDER_SET_NO_ISOLATED \ + Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, (int)BORDER_REFLECT, (int)BORDER_WRAP, (int)BORDER_REFLECT_101/*, \ + (int)BORDER_CONSTANT|BORDER_ISOLATED, (int)BORDER_REPLICATE|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 + +#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/*, \ + (int)BORDER_CONSTANT|BORDER_ISOLATED, (int)BORDER_REPLICATE|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 + + INSTANTIATE_TEST_CASE_P(Filter, Blur, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC4), Values(3, 5, 7), Values(Size(0, 0)), // not used - Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, (int)BORDER_REFLECT, (int)BORDER_REFLECT_101), + FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED, + Values(0.0), // not used Bool())); INSTANTIATE_TEST_CASE_P(Filter, LaplacianTest, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC3, CV_32FC4), Values(1, 3), Values(Size(0, 0)), // not used - Values(1, 2), // value is used as scale factor for kernel + FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED, + Values(1.0, 0.2, 3.0), // scalar Bool())); INSTANTIATE_TEST_CASE_P(Filter, Erode, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC3, CV_32FC4), Values(3, 5, 7), Values(Size(0, 0)), // not used - testing::Range(1, 4), + Values(0), // not used + Values(1.0, 2.0, 3.0), Bool())); INSTANTIATE_TEST_CASE_P(Filter, Dilate, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC3, CV_32FC4), Values(3, 5, 7), Values(Size(0, 0)), // not used - testing::Range(1, 4), + Values(0), // not used + Values(1.0, 2.0, 3.0), Bool())); INSTANTIATE_TEST_CASE_P(Filter, SobelTest, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC3, CV_32FC4), Values(3, 5), - Values(Size(1, 0), Size(1, 1), Size(2, 0), Size(2, 1)), - Values((int)BORDER_CONSTANT, (int)BORDER_REFLECT101, - (int)BORDER_REPLICATE, (int)BORDER_REFLECT), + 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())); INSTANTIATE_TEST_CASE_P(Filter, ScharrTest, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC3, CV_32FC4), - Values(0), // not used - Values(Size(0, 1), Size(1, 0)), - Values((int)BORDER_CONSTANT, (int)BORDER_REFLECT101, - (int)BORDER_REPLICATE, (int)BORDER_REFLECT), + Values(1), + Values(Size(0, 1), Size(1, 0)), // dx, dy + FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED, + Values(1.0, 0.2), // scalar Bool())); INSTANTIATE_TEST_CASE_P(Filter, GaussianBlurTest, Combine( Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_32FC1, CV_32FC4), Values(3, 5), Values(Size(0, 0)), // not used - Values((int)BORDER_CONSTANT, (int)BORDER_REFLECT101, - (int)BORDER_REPLICATE, (int)BORDER_REFLECT), + FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED, + Values(0.0), // not used Bool())); INSTANTIATE_TEST_CASE_P(Filter, Filter2D, testing::Combine( Values(CV_8UC1, CV_32FC1, CV_32FC4), - Values(3, 15, 25), - Values(Size(0, 0)), // not used - Values((int)BORDER_CONSTANT, (int)BORDER_REFLECT101, - (int)BORDER_REPLICATE, (int)BORDER_REFLECT), + Values(3, 15), // TODO 25: CPU implementation has some issues + Values(Size(-1, -1), Size(0, 0), Size(2, 1)), // anchor + FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED, + Values(0.0), // not used Bool())); INSTANTIATE_TEST_CASE_P(Filter, Bilateral, Combine( Values(CV_8UC1, CV_8UC3), Values(5, 9), Values(Size(0, 0)), // not used - Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, - (int)BORDER_REFLECT, (int)BORDER_WRAP, (int)BORDER_REFLECT_101), + FILTER_BORDER_SET_NO_ISOLATED, + Values(0.0), // not used Bool())); INSTANTIATE_TEST_CASE_P(Filter, AdaptiveBilateral, Combine( Values(CV_8UC1, CV_8UC3), Values(5, 9), Values(Size(0, 0)), // not used - Values((int)BORDER_CONSTANT, (int)BORDER_REPLICATE, - (int)BORDER_REFLECT, (int)BORDER_REFLECT_101), + FILTER_BORDER_SET_NO_WRAP_NO_ISOLATED, + Values(0.0), // not used Bool())); INSTANTIATE_TEST_CASE_P(Filter, MedianFilter, Combine( @@ -447,6 +463,7 @@ INSTANTIATE_TEST_CASE_P(Filter, MedianFilter, Combine( Values(3, 5), Values(Size(0, 0)), // not used Values(0), // not used + Values(0.0), // not used Bool())); #endif // HAVE_OPENCL diff --git a/modules/ocl/test/utility.hpp b/modules/ocl/test/utility.hpp index 5ad97b0..5eeb075 100644 --- a/modules/ocl/test/utility.hpp +++ b/modules/ocl/test/utility.hpp @@ -72,6 +72,13 @@ double checkNorm(const cv::Mat &m); double checkNorm(const cv::Mat &m1, const cv::Mat &m2); double checkSimilarity(const cv::Mat &m1, const cv::Mat &m2); +inline double checkNormRelative(const Mat &m1, const Mat &m2) +{ + return cv::norm(m1, m2, cv::NORM_INF) / + std::max((double)std::numeric_limits::epsilon(), + (double)std::max(cv::norm(m1, cv::NORM_INF), norm(m2, cv::NORM_INF))); +} + #define EXPECT_MAT_NORM(mat, eps) \ { \ EXPECT_LE(checkNorm(cv::Mat(mat)), eps) \ @@ -84,6 +91,13 @@ double checkSimilarity(const cv::Mat &m1, const cv::Mat &m2); EXPECT_LE(checkNorm(cv::Mat(mat1), cv::Mat(mat2)), eps); \ } +#define EXPECT_MAT_NEAR_RELATIVE(mat1, mat2, eps) \ +{ \ + ASSERT_EQ(mat1.type(), mat2.type()); \ + ASSERT_EQ(mat1.size(), mat2.size()); \ + EXPECT_LE(checkNormRelative(cv::Mat(mat1), cv::Mat(mat2)), eps); \ +} + #define EXPECT_MAT_SIMILAR(mat1, mat2, eps) \ { \ ASSERT_EQ(mat1.type(), mat2.type()); \ -- 2.7.4