From 4d28e8243c6fe78eeeef0a4f59d72c6812578f29 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Fri, 10 Jan 2014 00:14:48 +0400 Subject: [PATCH 01/10] 'master'-like Haar perf test --- modules/ocl/perf/perf_haar.cpp | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/modules/ocl/perf/perf_haar.cpp b/modules/ocl/perf/perf_haar.cpp index b7a1dd1a4..a6c107fe4 100644 --- a/modules/ocl/perf/perf_haar.cpp +++ b/modules/ocl/perf/perf_haar.cpp @@ -83,3 +83,53 @@ PERF_TEST(HaarFixture, Haar) else OCL_PERF_ELSE } + +using namespace std; +using namespace cv; +using namespace perf; +using std::tr1::make_tuple; +using std::tr1::get; + +typedef std::tr1::tuple Cascade_Image_MinSize_t; +typedef perf::TestBaseWithParam Cascade_Image_MinSize; + +PERF_TEST_P( Cascade_Image_MinSize, CascadeClassifier_UMat, + testing::Combine( + testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml") ), + testing::Values( string("cv/shared/lena.png"), + string("cv/cascadeandhog/images/bttf301.png"), + string("cv/cascadeandhog/images/class57.png") ), + testing::Values(30, 64, 90) ) ) +{ + const string cascasePath = get<0>(GetParam()); + const string imagePath = get<1>(GetParam()); + const int min_size = get<2>(GetParam()); + Size minSize(min_size, min_size); + + ocl::OclCascadeClassifier cc; + if (!cc.load( getDataPath(cascasePath) )) + FAIL() << "Can't load cascade file: " << getDataPath(cascasePath); + + Mat img = imread(getDataPath(imagePath), IMREAD_GRAYSCALE); + if (img.empty()) + FAIL() << "Can't load source image: " << getDataPath(imagePath); + + vector faces; + + equalizeHist(img, img); + declare.in(img).time(60); + + ocl::oclMat uimg(img); + + while(next()) + { + faces.clear(); + + startTimer(); + cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize); + stopTimer(); + } + + //sort(faces.begin(), faces.end(), comparators::RectLess()); + SANITY_CHECK_NOTHING();//(faces, min_size/5); +} From a7821c60e55be5968aec41f31349f58db789671e Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Mon, 13 Jan 2014 11:20:17 +0400 Subject: [PATCH 02/10] refactoring the test as it should be in 2.4 --- modules/ocl/perf/perf_haar.cpp | 52 +++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/modules/ocl/perf/perf_haar.cpp b/modules/ocl/perf/perf_haar.cpp index a6c107fe4..2fe01ee6e 100644 --- a/modules/ocl/perf/perf_haar.cpp +++ b/modules/ocl/perf/perf_haar.cpp @@ -105,31 +105,45 @@ PERF_TEST_P( Cascade_Image_MinSize, CascadeClassifier_UMat, const string imagePath = get<1>(GetParam()); const int min_size = get<2>(GetParam()); Size minSize(min_size, min_size); - - ocl::OclCascadeClassifier cc; - if (!cc.load( getDataPath(cascasePath) )) - FAIL() << "Can't load cascade file: " << getDataPath(cascasePath); - - Mat img = imread(getDataPath(imagePath), IMREAD_GRAYSCALE); - if (img.empty()) - FAIL() << "Can't load source image: " << getDataPath(imagePath); - vector faces; + Mat img = imread(getDataPath(imagePath), IMREAD_GRAYSCALE); + ASSERT_TRUE(!img.empty()) << "Can't load source image: " << getDataPath(imagePath); equalizeHist(img, img); - declare.in(img).time(60); + declare.in(img); - ocl::oclMat uimg(img); - - while(next()) + if (RUN_PLAIN_IMPL) { - faces.clear(); + CascadeClassifier cc; + ASSERT_TRUE(cc.load(getDataPath(cascasePath))) << "Can't load cascade file: " << getDataPath(cascasePath); - startTimer(); - cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize); - stopTimer(); + while (next()) + { + faces.clear(); + + startTimer(); + cc.detectMultiScale(img, faces, 1.1, 3, 0, minSize); + stopTimer(); + } } + else if (RUN_OCL_IMPL) + { + ocl::oclMat uimg(img); + ocl::OclCascadeClassifier cc; + ASSERT_TRUE(cc.load(getDataPath(cascasePath))) << "Can't load cascade file: " << getDataPath(cascasePath); - //sort(faces.begin(), faces.end(), comparators::RectLess()); - SANITY_CHECK_NOTHING();//(faces, min_size/5); + while (next()) + { + faces.clear(); + + startTimer(); + cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize); + stopTimer(); + } + } + else + OCL_PERF_ELSE + + //sort(faces.begin(), faces.end(), comparators::RectLess()); + SANITY_CHECK_NOTHING();//(faces, min_size/5); } From 5d2edced2670e4d2305b5799da9378f21c18d24e Mon Sep 17 00:00:00 2001 From: Daniil Osokin Date: Mon, 13 Jan 2014 11:41:54 +0400 Subject: [PATCH 03/10] Added throwing exception when saving untrained SVM model --- modules/ml/src/svm.cpp | 18 ++++++++++++------ modules/ml/test/test_save_load.cpp | 8 ++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 674365bb3..f15880521 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -2298,14 +2298,24 @@ void CvSVM::write_params( CvFileStorage* fs ) const } +static bool isSvmModelApplicable(int sv_total, int var_all, int var_count, int class_count) +{ + return (sv_total > 0 && var_count > 0 && var_count <= var_all && class_count >= 0); +} + + void CvSVM::write( CvFileStorage* fs, const char* name ) const { CV_FUNCNAME( "CvSVM::write" ); __BEGIN__; - int i, var_count = get_var_count(), df_count, class_count; + int i, var_count = get_var_count(), df_count; + int class_count = class_labels ? class_labels->cols : + params.svm_type == CvSVM::ONE_CLASS ? 1 : 0; const CvSVMDecisionFunc* df = decision_func; + if( !isSvmModelApplicable(sv_total, var_all, var_count, class_count) ) + CV_ERROR( CV_StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_ML_SVM ); @@ -2314,9 +2324,6 @@ void CvSVM::write( CvFileStorage* fs, const char* name ) const cvWriteInt( fs, "var_all", var_all ); cvWriteInt( fs, "var_count", var_count ); - class_count = class_labels ? class_labels->cols : - params.svm_type == CvSVM::ONE_CLASS ? 1 : 0; - if( class_count ) { cvWriteInt( fs, "class_count", class_count ); @@ -2454,7 +2461,6 @@ void CvSVM::read_params( CvFileStorage* fs, CvFileNode* svm_node ) __END__; } - void CvSVM::read( CvFileStorage* fs, CvFileNode* svm_node ) { const double not_found_dbl = DBL_MAX; @@ -2483,7 +2489,7 @@ void CvSVM::read( CvFileStorage* fs, CvFileNode* svm_node ) var_count = cvReadIntByName( fs, svm_node, "var_count", var_all ); class_count = cvReadIntByName( fs, svm_node, "class_count", 0 ); - if( sv_total <= 0 || var_all <= 0 || var_count <= 0 || var_count > var_all || class_count < 0 ) + if( !isSvmModelApplicable(sv_total, var_all, var_count, class_count) ) CV_ERROR( CV_StsParseError, "SVM model data is invalid, check sv_count, var_* and class_count tags" ); CV_CALL( class_labels = (CvMat*)cvReadByName( fs, svm_node, "class_labels" )); diff --git a/modules/ml/test/test_save_load.cpp b/modules/ml/test/test_save_load.cpp index 9fd31b9f2..7300185b4 100644 --- a/modules/ml/test/test_save_load.cpp +++ b/modules/ml/test/test_save_load.cpp @@ -155,6 +155,14 @@ TEST(ML_RTrees, save_load) { CV_SLMLTest test( CV_RTREES ); test.safe_run(); } TEST(ML_ERTrees, save_load) { CV_SLMLTest test( CV_ERTREES ); test.safe_run(); } +TEST(ML_SVM, throw_exception_when_save_untrained_model) +{ + SVM svm; + string filename = tempfile("svm.xml"); + ASSERT_THROW(svm.save(filename.c_str()), Exception); + remove(filename.c_str()); +} + TEST(DISABLED_ML_SVM, linear_save_load) { CvSVM svm1, svm2, svm3; From 4c99196399288d2a97af37366c9a938d9092f0f1 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Mon, 13 Jan 2014 18:12:30 +0400 Subject: [PATCH 04/10] adding `finish()` to flush CL queue, renaming the test to match 'master' branch --- modules/ocl/perf/perf_haar.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/ocl/perf/perf_haar.cpp b/modules/ocl/perf/perf_haar.cpp index 2fe01ee6e..86890a891 100644 --- a/modules/ocl/perf/perf_haar.cpp +++ b/modules/ocl/perf/perf_haar.cpp @@ -90,10 +90,10 @@ using namespace perf; using std::tr1::make_tuple; using std::tr1::get; -typedef std::tr1::tuple Cascade_Image_MinSize_t; -typedef perf::TestBaseWithParam Cascade_Image_MinSize; +typedef std::tr1::tuple OCL_Cascade_Image_MinSize_t; +typedef perf::TestBaseWithParam OCL_Cascade_Image_MinSize; -PERF_TEST_P( Cascade_Image_MinSize, CascadeClassifier_UMat, +PERF_TEST_P( OCL_Cascade_Image_MinSize, CascadeClassifier, testing::Combine( testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml") ), testing::Values( string("cv/shared/lena.png"), @@ -135,6 +135,7 @@ PERF_TEST_P( Cascade_Image_MinSize, CascadeClassifier_UMat, while (next()) { faces.clear(); + ocl::finish(); startTimer(); cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize); @@ -146,4 +147,5 @@ PERF_TEST_P( Cascade_Image_MinSize, CascadeClassifier_UMat, //sort(faces.begin(), faces.end(), comparators::RectLess()); SANITY_CHECK_NOTHING();//(faces, min_size/5); + // using SANITY_CHECK_NOTHING() since OCL and PLAIN version may find different faces number } From 49dfa5a17f00a82f0c160e20395c193b992d286e Mon Sep 17 00:00:00 2001 From: ahb Date: Mon, 13 Jan 2014 16:09:42 +0100 Subject: [PATCH 05/10] Fix the following error for ocl::getOpenCLPlatforms() on Ubuntu 12.04 with gcc 4.8 OpenCV Error: Unknown error code -6 (OpenCL function is not available: [clGetPlatformIDs]) in opencl_check_fn, file /home/ahb/software/opencv/modules/ocl/src/cl_runtime/cl_runtime.cpp, line 83 The issue results from modules/ocl/src/cl_runtime/cl_runtime.cpp checking for "linux" instead of "__linux__" (cp. http://sourceforge.net/p/predef/wiki/OperatingSystems/) Adjust all other occurrences of "defined(linux)" as well. --- 3rdparty/include/opencl/1.2/CL/cl.hpp | 2 +- modules/ocl/src/cl_runtime/cl_runtime.cpp | 2 +- modules/ocl/src/cl_runtime/clamdblas_runtime.cpp | 2 +- modules/ocl/src/cl_runtime/clamdfft_runtime.cpp | 2 +- .../src/cl_runtime/generator/template/clamdblas_runtime.cpp.in | 2 +- .../src/cl_runtime/generator/template/clamdfft_runtime.cpp.in | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/3rdparty/include/opencl/1.2/CL/cl.hpp b/3rdparty/include/opencl/1.2/CL/cl.hpp index 0480e3116..2502d4c52 100644 --- a/3rdparty/include/opencl/1.2/CL/cl.hpp +++ b/3rdparty/include/opencl/1.2/CL/cl.hpp @@ -210,7 +210,7 @@ #include #endif -#if defined(linux) || defined(__APPLE__) || defined(__MACOSX) +#if defined(__linux__) || defined(__APPLE__) || defined(__MACOSX) #include #include diff --git a/modules/ocl/src/cl_runtime/cl_runtime.cpp b/modules/ocl/src/cl_runtime/cl_runtime.cpp index a0d967c0b..c3a31ccc3 100644 --- a/modules/ocl/src/cl_runtime/cl_runtime.cpp +++ b/modules/ocl/src/cl_runtime/cl_runtime.cpp @@ -45,7 +45,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/ocl/src/cl_runtime/clamdblas_runtime.cpp b/modules/ocl/src/cl_runtime/clamdblas_runtime.cpp index 0a077db69..1256000c8 100644 --- a/modules/ocl/src/cl_runtime/clamdblas_runtime.cpp +++ b/modules/ocl/src/cl_runtime/clamdblas_runtime.cpp @@ -27,7 +27,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/ocl/src/cl_runtime/clamdfft_runtime.cpp b/modules/ocl/src/cl_runtime/clamdfft_runtime.cpp index 60cbecef2..f0fa769b7 100644 --- a/modules/ocl/src/cl_runtime/clamdfft_runtime.cpp +++ b/modules/ocl/src/cl_runtime/clamdfft_runtime.cpp @@ -27,7 +27,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/ocl/src/cl_runtime/generator/template/clamdblas_runtime.cpp.in b/modules/ocl/src/cl_runtime/generator/template/clamdblas_runtime.cpp.in index 8492edda9..0cf33bb7e 100644 --- a/modules/ocl/src/cl_runtime/generator/template/clamdblas_runtime.cpp.in +++ b/modules/ocl/src/cl_runtime/generator/template/clamdblas_runtime.cpp.in @@ -24,7 +24,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/ocl/src/cl_runtime/generator/template/clamdfft_runtime.cpp.in b/modules/ocl/src/cl_runtime/generator/template/clamdfft_runtime.cpp.in index aee6bd8ab..8e8fb42c4 100644 --- a/modules/ocl/src/cl_runtime/generator/template/clamdfft_runtime.cpp.in +++ b/modules/ocl/src/cl_runtime/generator/template/clamdfft_runtime.cpp.in @@ -24,7 +24,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include From 8ce691e67966954cbab1e61f123f8206a42b1e90 Mon Sep 17 00:00:00 2001 From: Daniil Osokin Date: Mon, 13 Jan 2014 14:20:42 +0400 Subject: [PATCH 06/10] Fixed cvtColor alpha channel docs --- modules/imgproc/doc/miscellaneous_transformations.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/imgproc/doc/miscellaneous_transformations.rst b/modules/imgproc/doc/miscellaneous_transformations.rst index e3c459d68..515d6128f 100644 --- a/modules/imgproc/doc/miscellaneous_transformations.rst +++ b/modules/imgproc/doc/miscellaneous_transformations.rst @@ -113,6 +113,8 @@ But in case of a non-linear transformation, an input RGB image should be normali If you use ``cvtColor`` with 8-bit images, the conversion will have some information lost. For many applications, this will not be noticeable but it is recommended to use 32-bit images in applications that need the full range of colors or that convert an image before an operation and then convert back. +If conversion adds the alpha channel, its value will set to the maximum of corresponding channel range: 255 for ``CV_8U``, 65535 for ``CV_16U``, 1 for ``CV_32F``. + The function can do the following transformations: * @@ -127,7 +129,7 @@ The function can do the following transformations: .. math:: - \text{Gray to RGB[A]:} \quad R \leftarrow Y, G \leftarrow Y, B \leftarrow Y, A \leftarrow 0 + \text{Gray to RGB[A]:} \quad R \leftarrow Y, G \leftarrow Y, B \leftarrow Y, A \leftarrow \max (ChannelRange) The conversion from a RGB image to gray is done with: From f02204847af64656a8bff7a4b5ec1f55df11643b Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Fri, 17 Jan 2014 13:02:35 +0400 Subject: [PATCH 07/10] Revert "fixed bug #3319" See 092f916 for explanation. This reverts commit 4f9c081dc313f8fdfee3f0a4572779ae13e27e40. --- modules/core/src/precomp.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index ec8dcc9f2..c53224e0a 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -129,14 +129,12 @@ template struct OpMax inline Size getContinuousSize( const Mat& m1, int widthScale=1 ) { - CV_Assert(m1.dims <= 2); return m1.isContinuous() ? Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); } inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 ) { - CV_Assert(m1.dims <= 2 && m1.size() == m2.size()); return (m1.flags & m2.flags & Mat::CONTINUOUS_FLAG) != 0 ? Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); } @@ -144,7 +142,6 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 ) inline Size getContinuousSize( const Mat& m1, const Mat& m2, const Mat& m3, int widthScale=1 ) { - CV_Assert(m1.dims <= 2 && m1.size() == m2.size() && m1.size() == m3.size()); return (m1.flags & m2.flags & m3.flags & Mat::CONTINUOUS_FLAG) != 0 ? Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); } @@ -153,7 +150,6 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2, const Mat& m3, const Mat& m4, int widthScale=1 ) { - CV_Assert(m1.dims <= 2 && m1.size() == m2.size() && m1.size() == m3.size() && m1.size() == m4.size()); return (m1.flags & m2.flags & m3.flags & m4.flags & Mat::CONTINUOUS_FLAG) != 0 ? Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); } @@ -162,7 +158,6 @@ inline Size getContinuousSize( const Mat& m1, const Mat& m2, const Mat& m3, const Mat& m4, const Mat& m5, int widthScale=1 ) { - CV_Assert(m1.dims <= 2 && m1.size() == m2.size() && m1.size() == m3.size() && m1.size() == m4.size() && m1.size() == m5.size()); return (m1.flags & m2.flags & m3.flags & m4.flags & m5.flags & Mat::CONTINUOUS_FLAG) != 0 ? Size(m1.cols*m1.rows*widthScale, 1) : Size(m1.cols*widthScale, m1.rows); } From ee97a5e7573e292ea0d029a257fea0542c38e4a5 Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Fri, 17 Jan 2014 14:13:21 +0400 Subject: [PATCH 08/10] Re-fix bug #3319 with less side effects. --- modules/core/src/copy.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index 894776bb3..b87d080de 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -286,6 +286,7 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const if( dims <= 2 ) { + CV_Assert( size() == mask.size() ); Size sz = getContinuousSize(*this, dst, mask, mcn); copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz); return; From 4e4a7d035335b8db373f479335abd095fc582446 Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Fri, 17 Jan 2014 14:16:22 +0400 Subject: [PATCH 09/10] Removed an unnecessary workaround for matrix-to-vector copyTo. --- modules/core/src/copy.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index b87d080de..b8d87fc22 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -232,10 +232,7 @@ void Mat::copyTo( OutputArray _dst ) const const uchar* sptr = data; uchar* dptr = dst.data; - // to handle the copying 1xn matrix => nx1 std vector. - Size sz = size() == dst.size() ? - getContinuousSize(*this, dst) : - getContinuousSize(*this); + Size sz = getContinuousSize(*this, dst); size_t len = sz.width*elemSize(); for( ; sz.height--; sptr += step, dptr += dst.step ) From 5f8d8c0069a715dd3dfbbcd6a01a6715e74571b2 Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Fri, 17 Jan 2014 14:18:31 +0400 Subject: [PATCH 10/10] Added a test for matrix-to-vector copy and convert. --- modules/core/test/test_mat.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 514b587d7..a6ebe152d 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -897,3 +897,24 @@ TEST(Core_Mat, reshape_1942) ); ASSERT_EQ(1, cn); } + +TEST(Core_Mat, copyNx1ToVector) +{ + cv::Mat_ src(5, 1); + cv::Mat_ ref_dst8; + cv::Mat_ ref_dst16; + std::vector dst8; + std::vector dst16; + + src << 1, 2, 3, 4, 5; + + src.copyTo(ref_dst8); + src.copyTo(dst8); + + ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst8, cv::Mat_(dst8)); + + src.convertTo(ref_dst16, CV_16U); + src.convertTo(dst16, CV_16U); + + ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_(dst16)); +}