From 56b2b450ce44e53c55dd268eba937edd465fdf2b Mon Sep 17 00:00:00 2001 From: LaurentBerger Date: Mon, 22 Jun 2015 22:21:30 +0200 Subject: [PATCH 1/4] A new constant in adaptivethreshold is created to calculate gaussianBlur with CV_32F. hence rouding error are avoided --- modules/imgproc/include/opencv2/imgproc.hpp | 4 +++- modules/imgproc/src/thresh.cpp | 14 +++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index a9fa7ae21e..14f4067a92 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -326,7 +326,9 @@ enum AdaptiveThresholdTypes { window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C . The default sigma (standard deviation) is used for the specified blockSize . See cv::getGaussianKernel*/ - ADAPTIVE_THRESH_GAUSSIAN_C = 1 + ADAPTIVE_THRESH_GAUSSIAN_C = 1, + /** Like ADAPTIVE_THRESH_GAUSSIAN_C except that GaussianBlur use CV_32F for blurring to avoid rounding error*/ + ADAPTIVE_THRESH_GAUSSIAN_C_FLOAT = 2 }; //! cv::undistort mode diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index 490bdff3e5..0eae14546e 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -1295,11 +1295,19 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, if( src.data != dst.data ) mean = dst; - if( method == ADAPTIVE_THRESH_MEAN_C ) + if (method == ADAPTIVE_THRESH_MEAN_C) boxFilter( src, mean, src.type(), Size(blockSize, blockSize), Point(-1,-1), true, BORDER_REPLICATE ); - else if( method == ADAPTIVE_THRESH_GAUSSIAN_C ) - GaussianBlur( src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE ); + else if (method == ADAPTIVE_THRESH_GAUSSIAN_C) + GaussianBlur(src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE); + else if (method == ADAPTIVE_THRESH_GAUSSIAN_C_FLOAT) + { + Mat srcfloat,meanfloat; + src.convertTo(srcfloat,CV_32F); + meanfloat=srcfloat; + GaussianBlur(srcfloat, meanfloat, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE); + meanfloat.convertTo(dst, src.type()); + } else CV_Error( CV_StsBadFlag, "Unknown/unsupported adaptive threshold method" ); From ca0114228c490b4d5c5687e253641b70bcecb931 Mon Sep 17 00:00:00 2001 From: LaurentBerger Date: Thu, 25 Jun 2015 07:51:06 +0200 Subject: [PATCH 2/4] In adaptiveThreshold ADAPTIVE_THRES_GAUSSIAN_C gaussianBlur is computed using float number --- modules/imgproc/include/opencv2/imgproc.hpp | 4 +--- modules/imgproc/src/thresh.cpp | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index 14f4067a92..a9fa7ae21e 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -326,9 +326,7 @@ enum AdaptiveThresholdTypes { window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C . The default sigma (standard deviation) is used for the specified blockSize . See cv::getGaussianKernel*/ - ADAPTIVE_THRESH_GAUSSIAN_C = 1, - /** Like ADAPTIVE_THRESH_GAUSSIAN_C except that GaussianBlur use CV_32F for blurring to avoid rounding error*/ - ADAPTIVE_THRESH_GAUSSIAN_C_FLOAT = 2 + ADAPTIVE_THRESH_GAUSSIAN_C = 1 }; //! cv::undistort mode diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index 0eae14546e..f9c946a173 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -1299,8 +1299,6 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, boxFilter( src, mean, src.type(), Size(blockSize, blockSize), Point(-1,-1), true, BORDER_REPLICATE ); else if (method == ADAPTIVE_THRESH_GAUSSIAN_C) - GaussianBlur(src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE); - else if (method == ADAPTIVE_THRESH_GAUSSIAN_C_FLOAT) { Mat srcfloat,meanfloat; src.convertTo(srcfloat,CV_32F); From 12362f76b13002700ed2234b25740e4e15def5ba Mon Sep 17 00:00:00 2001 From: LaurentBerger Date: Tue, 30 Jun 2015 10:51:50 +0200 Subject: [PATCH 3/4] Test for adaptive thresh will give FAIL_BAD_ACCURACY for old implementation of adaptivethreshold --- modules/imgproc/test/test_adpativethresh.cpp | 113 +++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 modules/imgproc/test/test_adpativethresh.cpp diff --git a/modules/imgproc/test/test_adpativethresh.cpp b/modules/imgproc/test/test_adpativethresh.cpp new file mode 100644 index 0000000000..19e342b3a5 --- /dev/null +++ b/modules/imgproc/test/test_adpativethresh.cpp @@ -0,0 +1,113 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" +#include + +using namespace cv; +using namespace std; + +class CV_Adaptivethresh : public cvtest::BaseTest +{ +public: + CV_Adaptivethresh(); + ~CV_Adaptivethresh(); +protected: + void run(int); +}; + +CV_Adaptivethresh::CV_Adaptivethresh() {} +CV_Adaptivethresh::~CV_Adaptivethresh() {} + +void CV_Adaptivethresh::run( int /* start_from */) +{ + string exp_path = string(ts->get_data_path()) + "adaptivethresh/lena_orig.png"; + Mat lena = imread(exp_path, 0); // CV_LOAD_IMAGE_GRAYSCALE=0 + if (lena.empty() ) + { + ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA ); + return; + } + int sum=0; + for (int i = 0; i < lena.rows; i++) + { + unsigned char *ptr = lena.ptr(i); + for (int j=0;jset_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); + return; + } + int windowSize[9] = {3,9,11,17,21,25,29,37,47}; + int expectedValueMean[9] = {96138,121836,124499,129096,130538,131330,131743,131616,131223}; + int expectedValueGaussNew[9] = {86308,112910,116197,122117,124672,126488,127855,129377,130387}; + int expectedValueGaussOld[9] = {88583,81365,154081,98049,149357,106414,179701,168433,90250}; + Mat im; + bool failed=false; + for(int i = 0; i<9; ++i ) + { + adaptiveThreshold( lena, im, 255,cv::ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,windowSize[i],0); + int numberWhite=countNonZero(im); + if (numberWhite != expectedValueMean[i]) + { + ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); + return; + } + adaptiveThreshold( lena, im, 255,cv::ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,windowSize[i],0); + if (numberWhite != expectedValueGaussNew[i]) + { + + if (numberWhite != expectedValueGaussOld[i]) + ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); + else + ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); + } + } + if (failed) + ts->set_failed_test_info(cvtest::TS::OK); + else + ts->set_failed_test_info(cvtest::TS::OK); +} + +TEST(Imgproc_Adaptivethresh, regression) { CV_Adaptivethresh test; test.safe_run(); } From a64d096369c93d5f09a0db999730b72b97e14020 Mon Sep 17 00:00:00 2001 From: LaurentBerger Date: Tue, 4 Aug 2015 22:58:22 +0200 Subject: [PATCH 4/4] remove test --- modules/imgproc/test/test_adpativethresh.cpp | 113 ------------------- 1 file changed, 113 deletions(-) delete mode 100644 modules/imgproc/test/test_adpativethresh.cpp diff --git a/modules/imgproc/test/test_adpativethresh.cpp b/modules/imgproc/test/test_adpativethresh.cpp deleted file mode 100644 index 19e342b3a5..0000000000 --- a/modules/imgproc/test/test_adpativethresh.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#include "test_precomp.hpp" -#include - -using namespace cv; -using namespace std; - -class CV_Adaptivethresh : public cvtest::BaseTest -{ -public: - CV_Adaptivethresh(); - ~CV_Adaptivethresh(); -protected: - void run(int); -}; - -CV_Adaptivethresh::CV_Adaptivethresh() {} -CV_Adaptivethresh::~CV_Adaptivethresh() {} - -void CV_Adaptivethresh::run( int /* start_from */) -{ - string exp_path = string(ts->get_data_path()) + "adaptivethresh/lena_orig.png"; - Mat lena = imread(exp_path, 0); // CV_LOAD_IMAGE_GRAYSCALE=0 - if (lena.empty() ) - { - ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA ); - return; - } - int sum=0; - for (int i = 0; i < lena.rows; i++) - { - unsigned char *ptr = lena.ptr(i); - for (int j=0;jset_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); - return; - } - int windowSize[9] = {3,9,11,17,21,25,29,37,47}; - int expectedValueMean[9] = {96138,121836,124499,129096,130538,131330,131743,131616,131223}; - int expectedValueGaussNew[9] = {86308,112910,116197,122117,124672,126488,127855,129377,130387}; - int expectedValueGaussOld[9] = {88583,81365,154081,98049,149357,106414,179701,168433,90250}; - Mat im; - bool failed=false; - for(int i = 0; i<9; ++i ) - { - adaptiveThreshold( lena, im, 255,cv::ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,windowSize[i],0); - int numberWhite=countNonZero(im); - if (numberWhite != expectedValueMean[i]) - { - ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); - return; - } - adaptiveThreshold( lena, im, 255,cv::ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,windowSize[i],0); - if (numberWhite != expectedValueGaussNew[i]) - { - - if (numberWhite != expectedValueGaussOld[i]) - ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); - else - ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); - } - } - if (failed) - ts->set_failed_test_info(cvtest::TS::OK); - else - ts->set_failed_test_info(cvtest::TS::OK); -} - -TEST(Imgproc_Adaptivethresh, regression) { CV_Adaptivethresh test; test.safe_run(); }