diff --git a/3rdparty/include/opencl/1.2/CL/cl.hpp b/3rdparty/include/opencl/1.2/CL/cl.hpp index 0480e31163..2502d4c52c 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/core/src/copy.cpp b/modules/core/src/copy.cpp index 472de6e1e1..3a712c4a9a 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -247,10 +247,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 ) @@ -301,6 +298,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; diff --git a/modules/core/src/opencl/runtime/opencl_clamdblas.cpp b/modules/core/src/opencl/runtime/opencl_clamdblas.cpp index e7ff79e3cd..1f06446aea 100644 --- a/modules/core/src/opencl/runtime/opencl_clamdblas.cpp +++ b/modules/core/src/opencl/runtime/opencl_clamdblas.cpp @@ -67,7 +67,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/core/src/opencl/runtime/opencl_clamdfft.cpp b/modules/core/src/opencl/runtime/opencl_clamdfft.cpp index d42bef9b81..a3a6eff0c3 100644 --- a/modules/core/src/opencl/runtime/opencl_clamdfft.cpp +++ b/modules/core/src/opencl/runtime/opencl_clamdfft.cpp @@ -67,7 +67,7 @@ #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/core/src/opencl/runtime/opencl_core.cpp b/modules/core/src/opencl/runtime/opencl_core.cpp index 238a5bdfb6..fb82c0d935 100644 --- a/modules/core/src/opencl/runtime/opencl_core.cpp +++ b/modules/core/src/opencl/runtime/opencl_core.cpp @@ -125,7 +125,7 @@ static void* WinGetProcAddress(const char* name) #define CV_CL_GET_PROC_ADDRESS(name) WinGetProcAddress(name) #endif // _WIN32 -#if defined(linux) +#if defined(__linux__) #include #include diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 3c8ae8bf9f..6b7e5fe039 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -1139,3 +1139,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)); +} diff --git a/modules/imgproc/doc/miscellaneous_transformations.rst b/modules/imgproc/doc/miscellaneous_transformations.rst index df63c929b5..5b32775812 100644 --- a/modules/imgproc/doc/miscellaneous_transformations.rst +++ b/modules/imgproc/doc/miscellaneous_transformations.rst @@ -110,6 +110,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: * @@ -124,7 +126,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: diff --git a/modules/ml/src/svm.cpp b/modules/ml/src/svm.cpp index 9f531ac4e7..84de4cd797 100644 --- a/modules/ml/src/svm.cpp +++ b/modules/ml/src/svm.cpp @@ -2347,14 +2347,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 ); @@ -2363,9 +2373,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 ); @@ -2503,7 +2510,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; @@ -2532,7 +2538,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 9fd31b9f24..7300185b4d 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; diff --git a/modules/ocl/perf/perf_haar.cpp b/modules/ocl/perf/perf_haar.cpp index 8e69b76485..37c14e3d33 100644 --- a/modules/ocl/perf/perf_haar.cpp +++ b/modules/ocl/perf/perf_haar.cpp @@ -85,3 +85,69 @@ 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 OCL_Cascade_Image_MinSize_t; +typedef perf::TestBaseWithParam OCL_Cascade_Image_MinSize; + +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"), + 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); + 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); + + if (RUN_PLAIN_IMPL) + { + CascadeClassifier cc; + ASSERT_TRUE(cc.load(getDataPath(cascasePath))) << "Can't load cascade file: " << getDataPath(cascasePath); + + 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); + + while (next()) + { + faces.clear(); + ocl::finish(); + + 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); + // using SANITY_CHECK_NOTHING() since OCL and PLAIN version may find different faces number +}