From 07fa62f0c4bd0cba21c98a0caaecaed1d81c9c7b Mon Sep 17 00:00:00 2001 From: Alexander Reshetnikov Date: Wed, 25 Jan 2012 13:41:48 +0000 Subject: [PATCH] some design code changes in new tests --- modules/calib3d/test/test_homography.cpp | 1299 ++++++-------------- modules/core/test/test_countnonzero.cpp | 300 ++--- modules/core/test/test_eigen.cpp | 433 ++++--- modules/imgproc/test/test_boundingrect.cpp | 136 +- 4 files changed, 870 insertions(+), 1298 deletions(-) diff --git a/modules/calib3d/test/test_homography.cpp b/modules/calib3d/test/test_homography.cpp index bb694b3ab3..11b18aaa12 100644 --- a/modules/calib3d/test/test_homography.cpp +++ b/modules/calib3d/test/test_homography.cpp @@ -30,41 +30,24 @@ using namespace std; class CV_HomographyTest: public cvtest::ArrayTest { - public: - - CV_HomographyTest(); - ~CV_HomographyTest(); - - int read_params( CvFileStorage* fs ); - void fill_array( int test_case_idx, int i, int j, Mat& arr ); - int prepare_test_case( int test_case_idx ); - void get_test_array_types_and_sizes( int test_case_idx, vector >& sizes, vector >& types ); - void run (int); - - bool check_matrix (const Mat& H); - bool check_transform (const Mat& src, const Mat& dst, const Mat& H); - - - void prepare_to_validation( int test_case_idx ); - - protected: - - int method; - int image_size; - int square_size; - double reproj_threshold; - double sigma; - bool test_cpp; - - double get_success_error_level( int test_case_idx, int i, int j ); - void test_projectPoints(Mat& src_2d, Mat& dst_2d, const Mat& H, RNG* rng, double sigma); // checking for quality of perpective transformation - - private: +public: + CV_HomographyTest(); + ~CV_HomographyTest(); + + void run (int); + +protected: + + int method; + int image_size; + double reproj_threshold; + double sigma; + +private: float max_diff, max_2diff; bool check_matrix_size(const cv::Mat& H); bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff); - // bool check_reproj_error(const cv::Mat& src_3d, const cv::Mat& dst_3d, const int norm_type = NORM_L2); - int check_ransac_mask_1(const Mat& src, const Mat& mask); + int check_ransac_mask_1(const Mat& src, const Mat& mask); int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask); void print_information_1(int j, int N, int method, const Mat& H); @@ -75,934 +58,472 @@ class CV_HomographyTest: public cvtest::ArrayTest void print_information_6(int j, int N, int k, double diff, bool value); void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value); void print_information_8(int j, int N, int k, int l, double diff); - - void check_transform_quality(cv::InputArray src_points, cv::InputArray dst_poits, const cv::Mat& H, const int norm_type = NORM_L2); - void check_transform_quality(const cv::InputArray src_points, const vector dst_points, const cv::Mat& H, const int norm_type = NORM_L2); - void check_transform_quality(const vector src_points, const cv::InputArray dst_points, const cv::Mat& H, const int norm_type = NORM_L2); - void check_transform_quality(const vector src_points, const vector dst_points, const cv::Mat& H, const int norm_type = NORM_L2); }; CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2), max_2diff(2e-2) { - test_array[INPUT].push_back(NULL); - test_array[INPUT].push_back(NULL); - test_array[INPUT].push_back(NULL); - test_array[INPUT].push_back(NULL); - test_array[INPUT].push_back(NULL); - test_array[INPUT].push_back(NULL); - test_array[TEMP].push_back(NULL); - test_array[TEMP].push_back(NULL); - test_array[OUTPUT].push_back(NULL); - test_array[OUTPUT].push_back(NULL); - test_array[REF_OUTPUT].push_back(NULL); - test_array[REF_OUTPUT].push_back(NULL); - - element_wise_relative_error = false; - - method = 0; - image_size = 1e+2; - reproj_threshold = 3.0; - sigma = 0.01; - - test_cpp = false; + method = 0; + image_size = 1e+2; + reproj_threshold = 3.0; + sigma = 0.01; } CV_HomographyTest::~CV_HomographyTest() {} -void CV_HomographyTest::get_test_array_types_and_sizes( int /*test_case_idx*/, vector >& sizes, vector >& types ) +bool CV_HomographyTest::check_matrix_size(const cv::Mat& H) { - RNG& rng = ts->get_rng(); - int pt_depth = CV_32F; - double pt_count_exp = cvtest::randReal(rng)*6 + 1; - int pt_count = cvRound(exp(pt_count_exp)); - - /* dims = cvtest::randInt(rng) % 2 + 2; - method = 1 << (cvtest::randInt(rng) % 4); - - if( method == CV_FM_7POINT ) - pt_count = 7; - else - { - pt_count = MAX( pt_count, 8 + (method == CV_FM_8POINT) ); - if( pt_count >= 8 && cvtest::randInt(rng) % 2 ) - method |= CV_FM_8POINT; - } */ - - types[INPUT][0] = CV_MAKETYPE(pt_depth, 2); - - types[INPUT][1] = types[INPUT][0]; - - types[OUTPUT][0] = CV_MAKETYPE(pt_depth, 1); - - /* if( cvtest::randInt(rng) % 2 ) - sizes[INPUT][0] = cvSize(pt_count, dims); - else - { - sizes[INPUT][0] = cvSize(dims, pt_count); - if( cvtest::randInt(rng) % 2 ) - { - types[INPUT][0] = CV_MAKETYPE(pt_depth, dims); - if( cvtest::randInt(rng) % 2 ) - sizes[INPUT][0] = cvSize(pt_count, 1); - else - sizes[INPUT][0] = cvSize(1, pt_count); - } - } - - sizes[INPUT][1] = sizes[INPUT][0]; - types[INPUT][1] = types[INPUT][0]; - - sizes[INPUT][2] = cvSize(pt_count, 1 ); - types[INPUT][2] = CV_64FC3; - - sizes[INPUT][3] = cvSize(4,3); - types[INPUT][3] = CV_64FC1; + return (H.rows == 3) && (H.cols == 3); +} - sizes[INPUT][4] = sizes[INPUT][5] = cvSize(3,3); - types[INPUT][4] = types[INPUT][5] = CV_MAKETYPE(CV_64F, 1); +bool CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff) +{ + diff = cv::norm(original, found, norm_type); + return diff <= max_diff; +} - sizes[TEMP][0] = cvSize(3,3); - types[TEMP][0] = CV_64FC1; - sizes[TEMP][1] = cvSize(pt_count,1); - types[TEMP][1] = CV_8UC1; +int CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask) +{ + if (!(mask.cols == 1) && (mask.rows == src.cols)) return 1; + if (countNonZero(mask) < mask.rows) return 2; + for (int i = 0; i < mask.rows; ++i) if (mask.at(i, 0) > 1) return 3; + return 0; +} - sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,1); - types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_64FC1; - sizes[OUTPUT][1] = sizes[REF_OUTPUT][1] = cvSize(pt_count,1); - types[OUTPUT][1] = types[REF_OUTPUT][1] = CV_8UC1; - - test_cpp = (cvtest::randInt(rng) & 256) == 0; - */ +int CV_HomographyTest::check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask) +{ + if (!(found_mask.cols == 1) && (found_mask.rows == original_mask.rows)) return 1; + for (int i = 0; i < found_mask.rows; ++i) if (found_mask.at(i, 0) > 1) return 2; + return 0; } -int CV_HomographyTest::read_params(CvFileStorage *fs) +void CV_HomographyTest::print_information_1(int j, int N, int method, const Mat& H) { - int code = cvtest::ArrayTest::read_params(fs); - return code; + cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Count of points: " << N << endl; cout << endl; + cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl; + cout << "Homography matrix:" << endl; cout << endl; + cout << H << endl; cout << endl; + cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl; } -double CV_HomographyTest::get_success_error_level(int test_case_idx, int i, int j) +void CV_HomographyTest::print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff) { - return max_diff; + cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Count of points: " << N << endl; cout << endl; + cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl; + cout << "Original matrix:" << endl; cout << endl; + cout << H << endl; cout << endl; + cout << "Found matrix:" << endl; cout << endl; + cout << H_res << endl; cout << endl; + cout << "Norm type using in criteria: "; if (NORM_TYPE[k] == 1) cout << "INF"; else if (NORM_TYPE[k] == 2) cout << "L1"; else cout << "L2"; cout << endl; + cout << "Difference between matrices: " << diff << endl; + cout << "Maximum allowed difference: " << max_diff << endl; cout << endl; } -void CV_HomographyTest::fill_array( int test_case_idx, int i, int j, Mat& arr ) +void CV_HomographyTest::print_information_3(int j, int N, const Mat& mask) { - double t[9]={0}; - RNG& rng = ts->get_rng(); + cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Count of points: " << N << endl; cout << endl; + cout << "Method: RANSAC" << endl; + cout << "Found mask:" << endl; cout << endl; + cout << mask << endl; cout << endl; + cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl; +} - if ( i != INPUT ) - { - cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr ); - return; - } +void CV_HomographyTest::print_information_4(int method, int j, int N, int k, int l, double diff) +{ + cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; + cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Sigma of normal noise: " << sigma << endl; + cout << "Count of points: " << N << endl; + cout << "Number of point: " << k << endl; + cout << "Norm type using in criteria: "; if (NORM_TYPE[l] == 1) cout << "INF"; else if (NORM_TYPE[l] == 2) cout << "L1"; else cout << "L2"; cout << endl; + cout << "Difference with noise of point: " << diff << endl; + cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl; +} - switch( j ) - { - case 0: - case 1: - return; // fill them later in prepare_test_case - case 2: - { - double* p = arr.ptr(); - for( i = 0; i < arr.cols*3; i += 3 ) - { - /* p[i] = cvtest::randReal(rng)*square_size; - p[i+1] = cvtest::randReal(rng)*square_size; - p[i+2] = cvtest::randReal(rng)*square_size + square_size; */ - } - } - break; - case 3: - { - double r[3]; - Mat rot_vec( 3, 1, CV_64F, r ); - Mat rot_mat( 3, 3, CV_64F, t, 4*sizeof(t[0]) ); - r[0] = cvtest::randReal(rng)*CV_PI*2; - r[1] = cvtest::randReal(rng)*CV_PI*2; - r[2] = cvtest::randReal(rng)*CV_PI*2; - - cvtest::Rodrigues( rot_vec, rot_mat ); - /* t[3] = cvtest::randReal(rng)*square_size; - t[7] = cvtest::randReal(rng)*square_size; - t[11] = cvtest::randReal(rng)*square_size; */ - Mat( 3, 4, CV_64F, t ).convertTo(arr, arr.type()); - } - break; - case 4: - case 5: - { - /* t[0] = t[4] = cvtest::randReal(rng)*(max_f - min_f) + min_f; - t[2] = (img_size*0.5 + cvtest::randReal(rng)*4. - 2.)*t[0]; - t[5] = (img_size*0.5 + cvtest::randReal(rng)*4. - 2.)*t[4]; - t[8] = 1.0f; - Mat( 3, 3, CV_64F, t ).convertTo( arr, arr.type() ); */ - break; - } - } +void CV_HomographyTest::print_information_5(int method, int j, int N, int l, double diff) +{ + cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; + cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Sigma of normal noise: " << sigma << endl; + cout << "Count of points: " << N << endl; + cout << "Norm type using in criteria: "; if (NORM_TYPE[l] == 1) cout << "INF"; else if (NORM_TYPE[l] == 2) cout << "L1"; else cout << "L2"; cout << endl; + cout << "Difference with noise of points: " << diff << endl; + cout << "Maxumum allowed difference: " << max_diff << endl; cout << endl; } -int CV_HomographyTest::prepare_test_case(int test_case_idx) +void CV_HomographyTest::print_information_6(int j, int N, int k, double diff, bool value) { - int code = cvtest::ArrayTest::prepare_test_case(test_case_idx); - - if (code > 0) - { - Mat& src = test_mat[INPUT][0]; - RNG& rng = ts->get_rng(); - - float Hdata[] = { sqrt(2.0f)/2, -sqrt(2.0f)/2, 0.0f, - sqrt(2.0f)/2, sqrt(2.0f)/2, 0.0f, - 0.0f, 0.0f, 1.0f }; - - Mat H( 3, 3, CV_32F, Hdata ); - - cv::Mat dst(1, src.cols, CV_32FC2); - - int k; - - for( k = 0; k < 2; k++ ) - { - const Mat& H = test_mat[OUTPUT][0]; - Mat& dst = test_mat[INPUT][k == 0 ? 1 : 2]; - - for (int i = 0; i < src.cols; ++i) - { - float *s = src.ptr()+2*i; - float *d = dst.ptr()+2*i; - - d[0] = Hdata[0]*s[0] + Hdata[1]*s[1] + Hdata[2]; - d[1] = Hdata[3]*s[0] + Hdata[4]*s[1] + Hdata[5]; - } - - test_projectPoints( src, dst, H, &rng, sigma ); - } - } - - return code; + cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; + cout << "Method: RANSAC" << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Count of points: " << N << " " << endl; + cout << "Number of point: " << k << " " << endl; + cout << "Reprojection error for this point: " << diff << " " << endl; + cout << "Reprojection error threshold: " << reproj_threshold << " " << endl; + cout << "Value of found mask: "<< value << endl; cout << endl; } -static void test_convertHomogeneous( const Mat& _src, Mat& _dst ) +void CV_HomographyTest::print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value) { - Mat src = _src, dst = _dst; - - int i, count, sdims, ddims; - int sstep1, sstep2, dstep1, dstep2; - - if( src.depth() != CV_64F ) _src.convertTo(src, CV_64F); - - if( dst.depth() != CV_64F ) dst.create(dst.size(), CV_MAKETYPE(CV_64F, _dst.channels())); - - if( src.rows > src.cols ) - { - count = src.rows; - sdims = src.channels()*src.cols; - sstep1 = (int)(src.step/sizeof(double)); - sstep2 = 1; - } - - else - { - count = src.cols; - sdims = src.channels()*src.rows; - if( src.rows == 1 ) - { - sstep1 = sdims; - sstep2 = 1; - } - - else - { - sstep1 = 1; - sstep2 = (int)(src.step/sizeof(double)); - } - } - - if( dst.rows > dst.cols ) - { - if (count != dst.rows) ; // CV_Error should be here - CV_Assert( count == dst.rows ); - ddims = dst.channels()*dst.cols; - dstep1 = (int)(dst.step/sizeof(double)); - dstep2 = 1; - } - else - { - assert( count == dst.cols ); - ddims = dst.channels()*dst.rows; - if( dst.rows == 1 ) - { - dstep1 = ddims; - dstep2 = 1; - } - else - { - dstep1 = 1; - dstep2 = (int)(dst.step/sizeof(double)); - } - } + cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; + cout << "Method: RANSAC" << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Count of points: " << N << " " << endl; + cout << "Number of point: " << k << " " << endl; + cout << "Reprojection error for this point: " << diff << " " << endl; + cout << "Reprojection error threshold: " << reproj_threshold << " " << endl; + cout << "Value of original mask: "<< original_value << " Value of found mask: " << found_value << endl; cout << endl; +} - double* s = src.ptr(); - double* d = dst.ptr(); +void CV_HomographyTest::print_information_8(int j, int N, int k, int l, double diff) +{ + cout << endl; cout << "Checking for reprojection error of inlier..." << endl; cout << endl; + cout << "Method: RANSAC" << endl; + cout << "Sigma of normal noise: " << sigma << endl; + cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector "; + cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; + cout << "Count of points: " << N << " " << endl; + cout << "Number of point: " << k << " " << endl; + cout << "Norm type using in criteria: "; if (NORM_TYPE[l] == 1) cout << "INF"; else if (NORM_TYPE[l] == 2) cout << "L1"; else cout << "L2"; cout << endl; + cout << "Difference with noise of point: " << diff << endl; + cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl; +} - if( sdims <= ddims ) +void CV_HomographyTest::run(int) +{ + for (size_t N = 4; N <= MAX_COUNT_OF_POINTS; ++N) { - int wstep = dstep2*(ddims - 1); + RNG& rng = ts->get_rng(); - for( i = 0; i < count; i++, s += sstep1, d += dstep1 ) - { - double x = s[0]; - double y = s[sstep2]; - - d[wstep] = 1; - d[0] = x; - d[dstep2] = y; + float *src_data = new float [2*N]; - if( sdims >= 3 ) - { - d[dstep2*2] = s[sstep2*2]; - if( sdims == 4 ) - d[dstep2*3] = s[sstep2*3]; - } + for (size_t i = 0; i < N; ++i) + { + src_data[2*i] = (float)cvtest::randReal(rng)*image_size; + src_data[2*i+1] = (float)cvtest::randReal(rng)*image_size; } - } - else - { - int wstep = sstep2*(sdims - 1); - for( i = 0; i < count; i++, s += sstep1, d += dstep1 ) - { - double w = s[wstep]; - double x = s[0]; - double y = s[sstep2]; + cv::Mat src_mat_2f(1, N, CV_32FC2, src_data), + src_mat_2d(2, N, CV_32F, src_data), + src_mat_3d(3, N, CV_32F); + cv::Mat dst_mat_2f, dst_mat_2d, dst_mat_3d; - w = w ? 1./w : 1; + vector src_vec, dst_vec; - d[0] = x*w; - d[dstep2] = y*w; + for (size_t i = 0; i < N; ++i) + { + float *tmp = src_mat_2d.ptr()+2*i; + src_mat_3d.at(0, i) = tmp[0]; + src_mat_3d.at(1, i) = tmp[1]; + src_mat_3d.at(2, i) = 1.0f; - if( ddims == 3 ) - d[dstep2*2] = s[sstep2*2]*w; + src_vec.push_back(Point2f(tmp[0], tmp[1])); } - } - if( dst.data != _dst.data ) - dst.convertTo(_dst, _dst.depth()); -} + double fi = cvtest::randReal(rng)*2*CV_PI; -void CV_HomographyTest::test_projectPoints( Mat& src_2d, Mat& dst, const Mat& H, RNG* rng, double sigma ) -{ - if (!src_2d.isContinuous()) - { - CV_Error(-1, ""); - return; - } - - cv::Mat src_3d(1, src_2d.cols, CV_32FC3); - - for (int i = 0; i < src_2d.cols; ++i) - { - float *c_3d = src_3d.ptr()+3*i; - float *c_2d = src_2d.ptr()+2*i; - - c_3d[0] = c_2d[0]; c_3d[1] = c_2d[1]; c_3d[2] = 1.0f; - } - - cv::Mat dst_3d; gemm(H, src_3d, 1, Mat(), 0, dst_3d); - - int i, count = src_2d.cols; - - Mat noise; - - if ( rng ) - { - if( sigma == 0 ) rng = 0; - else - { - noise.create( 1, count, CV_32FC2 ); - rng->fill(noise, RNG::NORMAL, Scalar::all(0), Scalar::all(sigma) ); - } - } - - cv::Mat dst_2d(1, count, CV_32FC2); - - for (size_t i = 0; i < count; ++i) - { - float *c_3d = dst_3d.ptr()+3*i; - float *c_2d = dst_2d.ptr()+2*i; - - c_2d[0] = c_3d[0]/c_3d[2]; - c_2d[1] = c_3d[1]/c_3d[2]; - } - - Mat temp( 1, count, CV_32FC2 ); - - for( i = 0; i < count; i++ ) - { - const double* M = src_2d.ptr() + 2*i; - double* m = temp.ptr() + 2*i; - double X = M[0], Y = M[1], Z = M[2]; - double u = H.at(0, 0)*X + H.at(0, 1)*Y + H.at(0, 2); - double v = H.at(1, 0)*X + H.at(1, 1)*Y + H.at(1, 2); - double s = H.at(2, 0)*X + H.at(2, 1)*Y + H.at(2, 2); - - if( !noise.empty() ) - { - u += noise.at(i).x*s; - v += noise.at(i).y*s; - } - - m[0] = u; - m[1] = v; - m[2] = s; - } - - test_convertHomogeneous( dst_2d, dst ); -} + double t_x = cvtest::randReal(rng)*sqrt(image_size*1.0), + t_y = cvtest::randReal(rng)*sqrt(image_size*1.0); -void CV_HomographyTest::prepare_to_validation(int test_case_idx) -{ - const Mat& H = test_mat[INPUT][3]; - - const Mat& A1 = test_mat[INPUT][4]; - const Mat& A2 = test_mat[INPUT][5]; - - double h0[9], h[9]; - Mat H0(3, 3, CV_32FC1, h0); + double Hdata[9] = { cos(fi), -sin(fi), t_x, + sin(fi), cos(fi), t_y, + 0.0f, 0.0f, 1.0f }; - Mat invA1, invA2, T; + cv::Mat H_64(3, 3, CV_64F, Hdata), H_32; - cv::invert(A1, invA1, CV_SVD); - cv::invert(A2, invA2, CV_SVD); + H_64.convertTo(H_32, CV_32F); - double tx = H.at(0, 2); - double ty = H.at(1, 2); - double tz = H.at(2, 2); + dst_mat_3d = H_32*src_mat_3d; - // double _t_x[] = { 0, -tz, ty, tz, 0, -tx, -ty, tx, 0 }; + dst_mat_2d.create(2, N, CV_32F); dst_mat_2f.create(1, N, CV_32FC2); - // F = (A2^-T)*[t]_x*R*(A1^-1) - /* cv::gemm( invA2, Mat( 3, 3, CV_64F, _t_x ), 1, Mat(), 0, T, CV_GEMM_A_T ); - cv::gemm( R, invA1, 1, Mat(), 0, invA2 ); - cv::gemm( T, invA2, 1, Mat(), 0, F0 ); */ - H0 *= 1./h0[8]; + for (size_t i = 0; i < N; ++i) + { + float *tmp_2f = dst_mat_2f.ptr()+2*i; + tmp_2f[0] = dst_mat_2d.at(0, i) = dst_mat_3d.at(0, i) /= dst_mat_3d.at(2, i); + tmp_2f[1] = dst_mat_2d.at(1, i) = dst_mat_3d.at(1, i) /= dst_mat_3d.at(2, i); + dst_mat_3d.at(2, i) = 1.0f; - uchar* status = test_mat[TEMP][1].data; - double err_level = get_success_error_level( test_case_idx, OUTPUT, 1 ); - uchar* mtfm1 = test_mat[REF_OUTPUT][1].data; - uchar* mtfm2 = test_mat[OUTPUT][1].data; - double* f_prop1 = (double*)test_mat[REF_OUTPUT][0].data; - double* f_prop2 = (double*)test_mat[OUTPUT][0].data; + dst_vec.push_back(Point2f(tmp_2f[0], tmp_2f[1])); + } - int i, pt_count = test_mat[INPUT][2].cols; - Mat p1( 1, pt_count, CV_64FC2 ); - Mat p2( 1, pt_count, CV_64FC2 ); + for (size_t i = 0; i < METHODS_COUNT; ++i) + { + method = METHOD[i]; + switch (method) + { + case 0: + case CV_LMEDS: + { + Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method), + cv::findHomography(src_mat_2f, dst_vec, method), + cv::findHomography(src_vec, dst_mat_2f, method), + cv::findHomography(src_vec, dst_vec, method) }; + + for (size_t j = 0; j < 4; ++j) + { + + if (!check_matrix_size(H_res_64[j])) + { + print_information_1(j, N, method, H_res_64[j]); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); + return; + } + + double diff; + + for (size_t k = 0; k < COUNT_NORM_TYPES; ++k) + if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff)) + { + print_information_2(j, N, method, H_64, H_res_64[j], k, diff); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF); + return; + } + } + + continue; + } + case CV_RANSAC: + { + cv::Mat mask [4]; double diff; + + Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask[0]), + cv::findHomography(src_mat_2f, dst_vec, CV_RANSAC, reproj_threshold, mask[1]), + cv::findHomography(src_vec, dst_mat_2f, CV_RANSAC, reproj_threshold, mask[2]), + cv::findHomography(src_vec, dst_vec, CV_RANSAC, reproj_threshold, mask[3]) }; + + for (size_t j = 0; j < 4; ++j) + { + + if (!check_matrix_size(H_res_64[j])) + { + print_information_1(j, N, method, H_res_64[j]); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); + return; + } + + for (size_t k = 0; k < COUNT_NORM_TYPES; ++k) + if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff)) + { + print_information_2(j, N, method, H_64, H_res_64[j], k, diff); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF); + return; + } + + int code = check_ransac_mask_1(src_mat_2f, mask[j]); + + if (code) + { + print_information_3(j, N, mask[j]); + + switch (code) + { + case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; } + case 2: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_2); break; } + case 3: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3); break; } + + default: break; + } + + return; + } - test_convertHomogeneous( test_mat[INPUT][0], p1 ); - test_convertHomogeneous( test_mat[INPUT][1], p2 ); + } - cvtest::convert(test_mat[TEMP][0], H0, H.type()); + continue; + } - if( method <= CV_FM_8POINT ) - memset( status, 1, pt_count ); + default: continue; + } + } - for( i = 0; i < pt_count; i++ ) - { - double x1 = p1.at(i).x; - double y1 = p1.at(i).y; - double x2 = p2.at(i).x; - double y2 = p2.at(i).y; - double n1 = 1./sqrt(x1*x1 + y1*y1 + 1); - double n2 = 1./sqrt(x2*x2 + y2*y2 + 1); - double t0 = fabs(h0[0]*x2*x1 + h0[1]*x2*y1 + h0[2]*x2 + - h0[3]*y2*x1 + h0[4]*y2*y1 + h0[5]*y2 + - h0[6]*x1 + h0[7]*y1 + h0[8])*n1*n2; - double t = fabs(h[0]*x2*x1 + h[1]*x2*y1 + h[2]*x2 + - h[3]*y2*x1 + h[4]*y2*y1 + h[5]*y2 + - h[6]*x1 + h[7]*y1 + h[8])*n1*n2; - mtfm1[i] = 1; - mtfm2[i] = !status[i] || t0 > err_level || t < err_level; - } + Mat noise_2f(1, N, CV_32FC2); + rng.fill(noise_2f, RNG::NORMAL, Scalar::all(0), Scalar::all(sigma)); - f_prop1[0] = 1; - f_prop1[1] = 1; - f_prop1[2] = 0; + cv::Mat mask(N, 1, CV_8UC1); - // f_prop2[0] = f_result != 0; - f_prop2[1] = h[8]; - f_prop2[2] = cv::determinant( H ); -} + for (size_t i = 0; i < N; ++i) + { + float *a = noise_2f.ptr()+2*i, *_2f = dst_mat_2f.ptr()+2*i; + _2f[0] += a[0]; _2f[1] += a[1]; + mask.at(i, 0) = !(sqrt(a[0]*a[0]+a[1]*a[1]) > reproj_threshold); + } -bool CV_HomographyTest::check_matrix_size(const cv::Mat& H) -{ - return (H.rows == 3) && (H.cols == 3); -} + for (size_t i = 0; i < METHODS_COUNT; ++i) + { + method = METHOD[i]; + switch (method) + { + case 0: + case CV_LMEDS: + { + Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f), + cv::findHomography(src_mat_2f, dst_vec), + cv::findHomography(src_vec, dst_mat_2f), + cv::findHomography(src_vec, dst_vec) }; -bool CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff) -{ - diff = cv::norm(original, found, norm_type); - return diff <= max_diff; -} + for (size_t j = 0; j < 4; ++j) + { -int CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask) -{ - if (!(mask.cols == 1) && (mask.rows == src.cols)) return 1; - if (countNonZero(mask) < mask.rows) return 2; - for (size_t i = 0; i < mask.rows; ++i) if (mask.at(i, 0) > 1) return 3; - return 0; -} + if (!check_matrix_size(H_res_64[j])) + { + print_information_1(j, N, method, H_res_64[j]); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); + return; + } -int CV_HomographyTest::check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask) -{ - if (!(found_mask.cols == 1) && (found_mask.rows == original_mask.rows)) return 1; - for (size_t i = 0; i < found_mask.rows; ++i) if (found_mask.at(i, 0) > 1) return 2; - return 0; -} + Mat H_res_32; H_res_64[j].convertTo(H_res_32, CV_32F); -void CV_HomographyTest::print_information_1(int j, int N, int method, const Mat& H) -{ - cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Count of points: " << N << endl; cout << endl; - cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl; - cout << "Homography matrix:" << endl; cout << endl; - cout << H << endl; cout << endl; - cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl; -} + cv::Mat dst_res_3d(3, N, CV_32F), noise_2d(2, N, CV_32F); -void CV_HomographyTest::print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff) -{ - cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Count of points: " << N << endl; cout << endl; - cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl; - cout << "Original matrix:" << endl; cout << endl; - cout << H << endl; cout << endl; - cout << "Found matrix:" << endl; cout << endl; - cout << H_res << endl; cout << endl; - cout << "Norm type using in criteria: "; if (NORM_TYPE[k] == 1) cout << "INF"; else if (NORM_TYPE[k] == 2) cout << "L1"; else cout << "L2"; cout << endl; - cout << "Difference between matrix: " << diff << endl; - cout << "Maximum allowed difference: " << max_diff << endl; cout << endl; -} + for (size_t k = 0; k < N; ++k) + { -void CV_HomographyTest::print_information_3(int j, int N, const Mat& mask) -{ - cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Count of points: " << N << endl; cout << endl; - cout << "Method: RANSAC" << endl; - cout << "Found mask:" << endl; cout << endl; - cout << mask << endl; cout << endl; - cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl; -} + Mat tmp_mat_3d = H_res_32*src_mat_3d.col(k); -void CV_HomographyTest::print_information_4(int method, int j, int N, int k, int l, double diff) -{ - cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; - cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Sigma of normal noise: " << sigma << endl; - cout << "Count of points: " << N << endl; - cout << "Number of point: " << k << endl; - cout << "Norm type using in criteria: "; if (NORM_TYPE[l] == 1) cout << "INF"; else if (NORM_TYPE[l] == 2) cout << "L1"; else cout << "L2"; cout << endl; - cout << "Difference with noise of point: " << diff << endl; - cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl; -} + dst_res_3d.at(0, k) = tmp_mat_3d.at(0, 0) /= tmp_mat_3d.at(2, 0); + dst_res_3d.at(1, k) = tmp_mat_3d.at(1, 0) /= tmp_mat_3d.at(2, 0); + dst_res_3d.at(2, k) = tmp_mat_3d.at(2, 0) = 1.0f; -void CV_HomographyTest::print_information_5(int method, int j, int N, int l, double diff) -{ - cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; - cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Sigma of normal noise: " << sigma << endl; - cout << "Count of points: " << N << endl; - cout << "Norm type using in criteria: "; if (NORM_TYPE[l] == 1) cout << "INF"; else if (NORM_TYPE[l] == 2) cout << "L1"; else cout << "L2"; cout << endl; - cout << "Difference with noise of points: " << diff << endl; - cout << "Maxumum allowed difference: " << max_diff << endl; cout << endl; -} + float *a = noise_2f.ptr()+2*k; + noise_2d.at(0, k) = a[0]; noise_2d.at(1, k) = a[1]; -void CV_HomographyTest::print_information_6(int j, int N, int k, double diff, bool value) -{ - cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; - cout << "Method: RANSAC" << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Count of points: " << N << " " << endl; - cout << "Number of point: " << k << " " << endl; - cout << "Reprojection error for this point: " << diff << " " << endl; - cout << "Reprojection error threshold: " << reproj_threshold << " " << endl; - cout << "Value of found mask: "<< value << endl; cout << endl; -} + for (size_t l = 0; l < COUNT_NORM_TYPES; ++l) + if (cv::norm(tmp_mat_3d, dst_mat_3d.col(k), NORM_TYPE[l]) - cv::norm(noise_2d.col(k), NORM_TYPE[l]) > max_2diff) + { + print_information_4(method, j, N, k, l, cv::norm(tmp_mat_3d, dst_mat_3d.col(k), NORM_TYPE[l]) - cv::norm(noise_2d.col(k), NORM_TYPE[l])); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_1); + return; + } -void CV_HomographyTest::print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value) -{ - cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; - cout << "Method: RANSAC" << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Count of points: " << N << " " << endl; - cout << "Number of point: " << k << " " << endl; - cout << "Reprojection error for this point: " << diff << " " << endl; - cout << "Reprojection error threshold: " << reproj_threshold << " " << endl; - cout << "Value of original mask: "<< original_value << " Value of found mask: " << found_value << endl; cout << endl; -} + } -void CV_HomographyTest::print_information_8(int j, int N, int k, int l, double diff) -{ - cout << endl; cout << "Checking for reprojection error of inlier..." << endl; cout << endl; - cout << "Method: RANSAC" << endl; - cout << "Sigma of normal noise: " << sigma << endl; - cout << "Type of srcPoints: "; if (0 <= j < 2) cout << "Mat of CV_32FC2"; else cout << "vector "; - cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector "; cout << endl; - cout << "Count of points: " << N << " " << endl; - cout << "Number of point: " << k << " " << endl; - cout << "Norm type using in criteria: "; if (NORM_TYPE[l] == 1) cout << "INF"; else if (NORM_TYPE[l] == 2) cout << "L1"; else cout << "L2"; cout << endl; - cout << "Difference with noise of point: " << diff << endl; - cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl; -} + Mat tmp_mat_3d = H_res_32*src_mat_3d; -void CV_HomographyTest::check_transform_quality(cv::InputArray src_points, cv::InputArray dst_points, const cv::Mat& H, const int norm_type) -{ - Mat src, dst_original; - cv::transpose(src_points.getMat(), src); cv::transpose(dst_points.getMat(), dst_original); - cv::Mat src_3d(src.rows+1, src.cols, CV_32FC1); - src_3d(Rect(0, 0, src.rows, src.cols)) = src; - src_3d(Rect(src.rows, 0, 1, src.cols)) = Mat(1, src.cols, CV_32FC1, Scalar(1.0f)); - - cv::Mat dst_found, dst_found_3d; - cv::multiply(H, src_3d, dst_found_3d); - dst_found = dst_found_3d/dst_found_3d.row(dst_found_3d.rows-1); - double reprojection_error = cv::norm(dst_original, dst_found, norm_type); - CV_Assert ( reprojection_error > max_diff ); -} + for (size_t l = 0; l < COUNT_NORM_TYPES; ++l) + if (cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[l]) - cv::norm(noise_2d, NORM_TYPE[l]) > max_diff) + { + print_information_5(method, j, N, l, cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[l]) - cv::norm(noise_2d, NORM_TYPE[l])); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_2); + return; + } -void CV_HomographyTest::run(int) -{ - for (size_t N = 4; N <= MAX_COUNT_OF_POINTS; ++N) - { - RNG& rng = ts->get_rng(); - - float *src_data = new float [2*N]; - - for (int i = 0; i < N; ++i) - { - src_data[2*i] = (float)cvtest::randReal(rng)*image_size; - src_data[2*i+1] = (float)cvtest::randReal(rng)*image_size; - } - - cv::Mat src_mat_2f(1, N, CV_32FC2, src_data), - src_mat_2d(2, N, CV_32F, src_data), - src_mat_3d(3, N, CV_32F); - cv::Mat dst_mat_2f, dst_mat_2d, dst_mat_3d; - - vector src_vec, dst_vec; - - for (size_t i = 0; i < N; ++i) - { - float *tmp = src_mat_2d.ptr()+2*i; - src_mat_3d.at(0, i) = tmp[0]; - src_mat_3d.at(1, i) = tmp[1]; - src_mat_3d.at(2, i) = 1.0f; - - src_vec.push_back(Point2f(tmp[0], tmp[1])); - } - - double fi = cvtest::randReal(rng)*2*CV_PI; - - double t_x = cvtest::randReal(rng)*sqrt(image_size*1.0), - t_y = cvtest::randReal(rng)*sqrt(image_size*1.0); - - double Hdata[9] = { cos(fi), -sin(fi), t_x, - sin(fi), cos(fi), t_y, - 0.0f, 0.0f, 1.0f }; - - cv::Mat H_64(3, 3, CV_64F, Hdata), H_32; - - H_64.convertTo(H_32, CV_32F); - - dst_mat_3d = H_32*src_mat_3d; - - dst_mat_2d.create(2, N, CV_32F); dst_mat_2f.create(1, N, CV_32FC2); - - for (size_t i = 0; i < N; ++i) - { - float *tmp_2f = dst_mat_2f.ptr()+2*i; - tmp_2f[0] = dst_mat_2d.at(0, i) = dst_mat_3d.at(0, i) /= dst_mat_3d.at(2, i); - tmp_2f[1] = dst_mat_2d.at(1, i) = dst_mat_3d.at(1, i) /= dst_mat_3d.at(2, i); - dst_mat_3d.at(2, i) = 1.0f; - - dst_vec.push_back(Point2f(tmp_2f[0], tmp_2f[1])); - } - - for (size_t i = 0; i < METHODS_COUNT; ++i) - { - method = METHOD[i]; - switch (method) - { - case 0: - case CV_LMEDS: - { - Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method), - cv::findHomography(src_mat_2f, dst_vec, method), - cv::findHomography(src_vec, dst_mat_2f, method), - cv::findHomography(src_vec, dst_vec, method) }; - - for (size_t j = 0; j < 4; ++j) - { - - if (!check_matrix_size(H_res_64[j])) - { - print_information_1(j, N, method, H_res_64[j]); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); - return; - } - - double diff; - - for (size_t k = 0; k < COUNT_NORM_TYPES; ++k) - if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff)) - { - print_information_2(j, N, method, H_64, H_res_64[j], k, diff); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF); - return; - } - } - - continue; - } - case CV_RANSAC: - { - cv::Mat mask [4]; double diff; - - Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask[0]), - cv::findHomography(src_mat_2f, dst_vec, CV_RANSAC, reproj_threshold, mask[1]), - cv::findHomography(src_vec, dst_mat_2f, CV_RANSAC, reproj_threshold, mask[2]), - cv::findHomography(src_vec, dst_vec, CV_RANSAC, reproj_threshold, mask[3]) }; - - for (size_t j = 0; j < 4; ++j) - { - - if (!check_matrix_size(H_res_64[j])) - { - print_information_1(j, N, method, H_res_64[j]); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); - return; - } - - for (size_t k = 0; k < COUNT_NORM_TYPES; ++k) - if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff)) - { - print_information_2(j, N, method, H_64, H_res_64[j], k, diff); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF); - return; - } - - int code = check_ransac_mask_1(src_mat_2f, mask[j]); - - if (code) - { - print_information_3(j, N, mask[j]); - - switch (code) - { - case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; } - case 2: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_2); break; } - case 3: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3); break; } - - default: break; - } - - return; - } - - } - - continue; - } - - default: continue; - } - } - - Mat noise_2f(1, N, CV_32FC2); - rng.fill(noise_2f, RNG::NORMAL, Scalar::all(0), Scalar::all(sigma)); - - cv::Mat mask(N, 1, CV_8UC1); - - for (int i = 0; i < N; ++i) - { - float *a = noise_2f.ptr()+2*i, *_2f = dst_mat_2f.ptr()+2*i; - _2f[0] /* = dst_mat_2d.at(0, i) = dst_mat_3d.at(0, i) */ += a[0]; - _2f[1] /* = dst_mat_2d.at(1, i) = dst_mat_3d.at(1, i) */ += a[1]; - mask.at(i, 0) = !(sqrt(a[0]*a[0]+a[1]*a[1]) > reproj_threshold); - } - - for (size_t i = 0; i < METHODS_COUNT; ++i) - { - method = METHOD[i]; - switch (method) - { - case 0: - case CV_LMEDS: - { - Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f), - cv::findHomography(src_mat_2f, dst_vec), - cv::findHomography(src_vec, dst_mat_2f), - cv::findHomography(src_vec, dst_vec) }; - - for (size_t j = 0; j < 4; ++j) - { - - if (!check_matrix_size(H_res_64[j])) - { - print_information_1(j, N, method, H_res_64[j]); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); - return; - } - - Mat H_res_32; H_res_64[j].convertTo(H_res_32, CV_32F); - - cv::Mat dst_res_3d(3, N, CV_32F), noise_2d(2, N, CV_32F); - - for (size_t k = 0; k < N; ++k) - { - - Mat tmp_mat_3d = H_res_32*src_mat_3d.col(k); - - dst_res_3d.at(0, k) = tmp_mat_3d.at(0, 0) /= tmp_mat_3d.at(2, 0); - dst_res_3d.at(1, k) = tmp_mat_3d.at(1, 0) /= tmp_mat_3d.at(2, 0); - dst_res_3d.at(2, k) = tmp_mat_3d.at(2, 0) = 1.0f; - - float *a = noise_2f.ptr()+2*k; - noise_2d.at(0, k) = a[0]; noise_2d.at(1, k) = a[1]; - - for (size_t l = 0; l < COUNT_NORM_TYPES; ++l) - if (cv::norm(tmp_mat_3d, dst_mat_3d.col(k), NORM_TYPE[l]) - cv::norm(noise_2d.col(k), NORM_TYPE[l]) > max_2diff) - { - print_information_4(method, j, N, k, l, cv::norm(tmp_mat_3d, dst_mat_3d.col(k), NORM_TYPE[l]) - cv::norm(noise_2d.col(k), NORM_TYPE[l])); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_1); - return; - } - - } - - Mat tmp_mat_3d = H_res_32*src_mat_3d; - - for (size_t l = 0; l < COUNT_NORM_TYPES; ++l) - if (cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[l]) - cv::norm(noise_2d, NORM_TYPE[l]) > max_diff) - { - print_information_5(method, j, N, l, cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[l]) - cv::norm(noise_2d, NORM_TYPE[l])); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_2); - return; - } - - } - - continue; + } + + continue; } - case CV_RANSAC: - { - cv::Mat mask_res [4]; - - Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res[0]), - cv::findHomography(src_mat_2f, dst_vec, CV_RANSAC, reproj_threshold, mask_res[1]), - cv::findHomography(src_vec, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res[2]), - cv::findHomography(src_vec, dst_vec, CV_RANSAC, reproj_threshold, mask_res[3]) }; - - for (size_t j = 0; j < 4; ++j) - { - - if (!check_matrix_size(H_res_64[j])) - { - print_information_1(j, N, method, H_res_64[j]); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); - return; - } - - int code = check_ransac_mask_2(mask, mask_res[j]); - - if (code) - { - print_information_3(j, N, mask_res[j]); - - switch (code) - { - case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; } - case 2: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3); break; } - - default: break; - } - - return; - } - - cv::Mat H_res_32; H_res_64[j].convertTo(H_res_32, CV_32F); - - cv::Mat dst_res_3d = H_res_32*src_mat_3d; - - for (size_t k = 0; k < N; ++k) - { - dst_res_3d.at(0, k) /= dst_res_3d.at(2, k); - dst_res_3d.at(1, k) /= dst_res_3d.at(2, k); - dst_res_3d.at(2, k) = 1.0f; - - float *p = dst_mat_2f.ptr()+2*k; - - dst_mat_3d.at(0, k) = p[0]; - dst_mat_3d.at(1, k) = p[1]; - - double diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_L2); - - if (mask_res[j].at(k, 0) != (diff <= reproj_threshold)) - { - print_information_6(j, N, k, diff, mask_res[j].at(k, 0)); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_4); - return; - } - - if (mask.at(k, 0) && !mask_res[j].at(k, 0)) - { - print_information_7(j, N, k, diff, mask.at(k, 0), mask_res[j].at(k, 0)); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_5); - return; - } - - if (mask_res[j].at(k, 0)) - { - float *a = noise_2f.ptr()+2*k; - dst_mat_3d.at(0, k) -= a[0]; - dst_mat_3d.at(1, k) -= a[1]; - - cv::Mat noise_2d(2, 1, CV_32F); - noise_2d.at(0, 0) = a[0]; noise_2d.at(1, 0) = a[1]; - - for (size_t l = 0; l < COUNT_NORM_TYPES; ++l) - { - diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_TYPE[l]); - - if (diff - cv::norm(noise_2d, NORM_TYPE[l]) > max_2diff) - { - print_information_8(j, N, k, l, diff - cv::norm(noise_2d, NORM_TYPE[l])); - CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF, MESSAGE_RANSAC_DIFF); - return; - } - } - } - } - } + case CV_RANSAC: + { + cv::Mat mask_res [4]; + + Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res[0]), + cv::findHomography(src_mat_2f, dst_vec, CV_RANSAC, reproj_threshold, mask_res[1]), + cv::findHomography(src_vec, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res[2]), + cv::findHomography(src_vec, dst_vec, CV_RANSAC, reproj_threshold, mask_res[3]) }; + + for (size_t j = 0; j < 4; ++j) + { + + if (!check_matrix_size(H_res_64[j])) + { + print_information_1(j, N, method, H_res_64[j]); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); + return; + } + + int code = check_ransac_mask_2(mask, mask_res[j]); + + if (code) + { + print_information_3(j, N, mask_res[j]); + + switch (code) + { + case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; } + case 2: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3); break; } + + default: break; + } + + return; + } + + cv::Mat H_res_32; H_res_64[j].convertTo(H_res_32, CV_32F); + + cv::Mat dst_res_3d = H_res_32*src_mat_3d; + + for (size_t k = 0; k < N; ++k) + { + dst_res_3d.at(0, k) /= dst_res_3d.at(2, k); + dst_res_3d.at(1, k) /= dst_res_3d.at(2, k); + dst_res_3d.at(2, k) = 1.0f; + + float *p = dst_mat_2f.ptr()+2*k; + + dst_mat_3d.at(0, k) = p[0]; + dst_mat_3d.at(1, k) = p[1]; + + double diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_L2); + + if (mask_res[j].at(k, 0) != (diff <= reproj_threshold)) + { + print_information_6(j, N, k, diff, mask_res[j].at(k, 0)); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_4); + return; + } + + if (mask.at(k, 0) && !mask_res[j].at(k, 0)) + { + print_information_7(j, N, k, diff, mask.at(k, 0), mask_res[j].at(k, 0)); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_5); + return; + } + + if (mask_res[j].at(k, 0)) + { + float *a = noise_2f.ptr()+2*k; + dst_mat_3d.at(0, k) -= a[0]; + dst_mat_3d.at(1, k) -= a[1]; + + cv::Mat noise_2d(2, 1, CV_32F); + noise_2d.at(0, 0) = a[0]; noise_2d.at(1, 0) = a[1]; + + for (size_t l = 0; l < COUNT_NORM_TYPES; ++l) + { + diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_TYPE[l]); + + if (diff - cv::norm(noise_2d, NORM_TYPE[l]) > max_2diff) + { + print_information_8(j, N, k, l, diff - cv::norm(noise_2d, NORM_TYPE[l])); + CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF, MESSAGE_RANSAC_DIFF); + return; + } + } + } + } + } - continue; - } - - default: continue; - } - } - } + continue; + } + + default: continue; + } + } + } } -TEST(Calib3d_Homography, complex_test) { CV_HomographyTest test; test.safe_run(); } \ No newline at end of file +TEST(Calib3d_Homography, accuracy) { CV_HomographyTest test; test.safe_run(); } diff --git a/modules/core/test/test_countnonzero.cpp b/modules/core/test/test_countnonzero.cpp index f6e446bab5..03b7b85b8d 100644 --- a/modules/core/test/test_countnonzero.cpp +++ b/modules/core/test/test_countnonzero.cpp @@ -18,26 +18,26 @@ const int INT_TYPE [5] = {CV_8U, CV_8S, CV_16U, CV_16S, CV_32S}; class CV_CountNonZeroTest: public cvtest::BaseTest { - public: +public: CV_CountNonZeroTest(); ~CV_CountNonZeroTest(); - protected: +protected: void run (int); - private: - float eps_32; - double eps_64; - Mat src; - int current_type; +private: + float eps_32; + double eps_64; + Mat src; + int current_type; - void generate_src_data(cv::Size size, int type); - void generate_src_data(cv::Size size, int type, int count_non_zero); - void generate_src_stat_data(cv::Size size, int type, int distribution); + void generate_src_data(cv::Size size, int type); + void generate_src_data(cv::Size size, int type, int count_non_zero); + void generate_src_stat_data(cv::Size size, int type, int distribution); - int get_count_non_zero(); + int get_count_non_zero(); - void print_information(int right, int result); + void print_information(int right, int result); }; CV_CountNonZeroTest::CV_CountNonZeroTest(): eps_32(1e-8), eps_64(1e-16), src(Mat()), current_type(-1) {} @@ -45,174 +45,174 @@ CV_CountNonZeroTest::~CV_CountNonZeroTest() {} void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type) { - src.create(size, CV_MAKETYPE(type, 1)); - - for (size_t j = 0; j < size.width; ++j) - for (size_t i = 0; i < size.height; ++i) - switch (type) - { - case CV_8U: { src.at(i, j) = cv::randu(); break; } - case CV_8S: { src.at(i, j) = cv::randu() - 128; break; } - case CV_16U: { src.at(i, j) = cv::randu(); break; } - case CV_16S: { src.at(i, j) = cv::randu(); break; } - case CV_32S: { src.at(i, j) = cv::randu(); break; } - case CV_32F: { src.at(i, j) = cv::randu(); break; } - case CV_64F: { src.at(i, j) = cv::randu(); break; } - default: break; - } + src.create(size, CV_MAKETYPE(type, 1)); + + for (int j = 0; j < size.width; ++j) + for (int i = 0; i < size.height; ++i) + switch (type) + { + case CV_8U: { src.at(i, j) = cv::randu(); break; } + case CV_8S: { src.at(i, j) = cv::randu() - 128; break; } + case CV_16U: { src.at(i, j) = cv::randu(); break; } + case CV_16S: { src.at(i, j) = cv::randu(); break; } + case CV_32S: { src.at(i, j) = cv::randu(); break; } + case CV_32F: { src.at(i, j) = cv::randu(); break; } + case CV_64F: { src.at(i, j) = cv::randu(); break; } + default: break; + } } void CV_CountNonZeroTest::generate_src_data(cv::Size size, int type, int count_non_zero) { - src = Mat::zeros(size, CV_MAKETYPE(type, 1)); - - int n = 0; RNG& rng = ts->get_rng(); - - while (n < count_non_zero) - { - size_t i = rng.next()%size.height, j = rng.next()%size.width; - - switch (type) - { - case CV_8U: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += (src.at(i, j) > 0);} break; } - case CV_8S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu() - 128; n += abs(sign(src.at(i, j)));} break; } - case CV_16U: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += (src.at(i, j) > 0);} break; } - case CV_16S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += abs(sign(src.at(i, j)));} break; } - case CV_32S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += abs(sign(src.at(i, j)));} break; } - case CV_32F: { if (fabs(src.at(i, j)) <= eps_32) {src.at(i, j) = cv::randu(); n += (fabs(src.at(i, j)) > eps_32);} break; } - case CV_64F: { if (fabs(src.at(i, j)) <= eps_64) {src.at(i, j) = cv::randu(); n += (fabs(src.at(i, j)) > eps_64);} break; } - - default: break; - } - } - + src = Mat::zeros(size, CV_MAKETYPE(type, 1)); + + int n = 0; RNG& rng = ts->get_rng(); + + while (n < count_non_zero) + { + size_t i = rng.next()%size.height, j = rng.next()%size.width; + + switch (type) + { + case CV_8U: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += (src.at(i, j) > 0);} break; } + case CV_8S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu() - 128; n += abs(sign(src.at(i, j)));} break; } + case CV_16U: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += (src.at(i, j) > 0);} break; } + case CV_16S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += abs(sign(src.at(i, j)));} break; } + case CV_32S: { if (!src.at(i, j)) {src.at(i, j) = cv::randu(); n += abs(sign(src.at(i, j)));} break; } + case CV_32F: { if (fabs(src.at(i, j)) <= eps_32) {src.at(i, j) = cv::randu(); n += (fabs(src.at(i, j)) > eps_32);} break; } + case CV_64F: { if (fabs(src.at(i, j)) <= eps_64) {src.at(i, j) = cv::randu(); n += (fabs(src.at(i, j)) > eps_64);} break; } + + default: break; + } + } + } void CV_CountNonZeroTest::generate_src_stat_data(cv::Size size, int type, int distribution) { - src.create(size, CV_MAKETYPE(type, 1)); + src.create(size, CV_MAKETYPE(type, 1)); - double mean = 0.0, sigma = 1.0; - double left = -1.0, right = 1.0; + double mean = 0.0, sigma = 1.0; + double left = -1.0, right = 1.0; - RNG& rng = ts->get_rng(); + RNG& rng = ts->get_rng(); - if (distribution == RNG::NORMAL) - rng.fill(src, RNG::NORMAL, Scalar::all(mean), Scalar::all(sigma)); - else if (distribution == RNG::UNIFORM) - rng.fill(src, RNG::UNIFORM, Scalar::all(left), Scalar::all(right)); + if (distribution == RNG::NORMAL) + rng.fill(src, RNG::NORMAL, Scalar::all(mean), Scalar::all(sigma)); + else if (distribution == RNG::UNIFORM) + rng.fill(src, RNG::UNIFORM, Scalar::all(left), Scalar::all(right)); } int CV_CountNonZeroTest::get_count_non_zero() { - int result = 0; + int result = 0; + + for (int i = 0; i < src.rows; ++i) + for (int j = 0; j < src.cols; ++j) - for (size_t i = 0; i < src.rows; ++i) - for (size_t j = 0; j < src.cols; ++j) + if (current_type == CV_8U) result += (src.at(i, j) > 0); - if (current_type == CV_8U) result += (src.at(i, j) > 0); - - else if (current_type == CV_8S) result += abs(sign(src.at(i, j))); + else if (current_type == CV_8S) result += abs(sign(src.at(i, j))); - else if (current_type == CV_16U) result += (src.at(i, j) > 0); + else if (current_type == CV_16U) result += (src.at(i, j) > 0); - else if (current_type == CV_16S) result += abs(sign(src.at(i, j))); + else if (current_type == CV_16S) result += abs(sign(src.at(i, j))); - else if (current_type == CV_32S) result += abs(sign(src.at(i, j))); + else if (current_type == CV_32S) result += abs(sign(src.at(i, j))); - else if (current_type == CV_32F) result += (fabs(src.at(i, j)) > eps_32); + else if (current_type == CV_32F) result += (fabs(src.at(i, j)) > eps_32); - else result += (fabs(src.at(i, j)) > eps_64); + else result += (fabs(src.at(i, j)) > eps_64); - return result; + return result; } void CV_CountNonZeroTest::print_information(int right, int result) { - cout << endl; cout << "Checking for the work of countNonZero function..." << endl; cout << endl; - cout << "Type of Mat: "; - switch (current_type) - { - case 0: {cout << "CV_8U"; break;} - case 1: {cout << "CV_8S"; break;} - case 2: {cout << "CV_16U"; break;} - case 3: {cout << "CV_16S"; break;} - case 4: {cout << "CV_32S"; break;} - case 5: {cout << "CV_32F"; break;} - case 6: {cout << "CV_64F"; break;} - default: break; - } - cout << endl; - cout << "Number of rows: " << src.rows << " Number of cols: " << src.cols << endl; - cout << "True count non zero elements: " << right << " Result: " << result << endl; - cout << endl; + cout << endl; cout << "Checking for the work of countNonZero function..." << endl; cout << endl; + cout << "Type of Mat: "; + switch (current_type) + { + case 0: {cout << "CV_8U"; break;} + case 1: {cout << "CV_8S"; break;} + case 2: {cout << "CV_16U"; break;} + case 3: {cout << "CV_16S"; break;} + case 4: {cout << "CV_32S"; break;} + case 5: {cout << "CV_32F"; break;} + case 6: {cout << "CV_64F"; break;} + default: break; + } + cout << endl; + cout << "Number of rows: " << src.rows << " Number of cols: " << src.cols << endl; + cout << "True count non zero elements: " << right << " Result: " << result << endl; + cout << endl; } void CV_CountNonZeroTest::run(int) { - const size_t N = 1500; - - for (int k = 1; k <= 3; ++k) - for (size_t i = 0; i < N; ++i) - { - RNG& rng = ts->get_rng(); - - int w = rng.next()%MAX_WIDTH + 1, h = rng.next()%MAX_HEIGHT + 1; - - current_type = rng.next()%7; - - switch (k) - { - case 1: { - generate_src_data(Size(w, h), current_type); - int right = get_count_non_zero(), result = countNonZero(src); - if (result != right) - { - cout << "Number of experiment: " << i << endl; - cout << "Method of data generation: RANDOM" << endl; - print_information(right, result); - CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); - return; - } - - break; - } - - case 2: { - int count_non_zero = rng.next()%(w*h); - generate_src_data(Size(w, h), current_type, count_non_zero); - int result = countNonZero(src); - if (result != count_non_zero) - { - cout << "Number of experiment: " << i << endl; - cout << "Method of data generation: HALF-RANDOM" << endl; - print_information(count_non_zero, result); - CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); - return; - } - - break; - } - - case 3: { - int distribution = cv::randu()%2; - generate_src_stat_data(Size(w, h), current_type, distribution); - int right = get_count_non_zero(), result = countNonZero(src); - if (right != result) - { - cout << "Number of experiment: " << i << endl; - cout << "Method of data generation: STATISTIC" << endl; - print_information(right, result); - CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); - return; - } - - break; - } - - default: break; - } - } + const size_t N = 1500; + + for (int k = 1; k <= 3; ++k) + for (size_t i = 0; i < N; ++i) + { + RNG& rng = ts->get_rng(); + + int w = rng.next()%MAX_WIDTH + 1, h = rng.next()%MAX_HEIGHT + 1; + + current_type = rng.next()%7; + + switch (k) + { + case 1: { + generate_src_data(Size(w, h), current_type); + int right = get_count_non_zero(), result = countNonZero(src); + if (result != right) + { + cout << "Number of experiment: " << i << endl; + cout << "Method of data generation: RANDOM" << endl; + print_information(right, result); + CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return; + } + + break; + } + + case 2: { + int count_non_zero = rng.next()%(w*h); + generate_src_data(Size(w, h), current_type, count_non_zero); + int result = countNonZero(src); + if (result != count_non_zero) + { + cout << "Number of experiment: " << i << endl; + cout << "Method of data generation: HALF-RANDOM" << endl; + print_information(count_non_zero, result); + CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return; + } + + break; + } + + case 3: { + int distribution = cv::randu()%2; + generate_src_stat_data(Size(w, h), current_type, distribution); + int right = get_count_non_zero(), result = countNonZero(src); + if (right != result) + { + cout << "Number of experiment: " << i << endl; + cout << "Method of data generation: STATISTIC" << endl; + print_information(right, result); + CV_Error(CORE_COUNTNONZERO_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return; + } + + break; + } + + default: break; + } + } } -// TEST (Core_CountNonZero, accuracy) { CV_CountNonZeroTest test; test.safe_run(); } \ No newline at end of file +// TEST (Core_CountNonZero, accuracy) { CV_CountNonZeroTest test; test.safe_run(); } diff --git a/modules/core/test/test_eigen.cpp b/modules/core/test/test_eigen.cpp index 8af108ac83..60da9d267d 100644 --- a/modules/core/test/test_eigen.cpp +++ b/modules/core/test/test_eigen.cpp @@ -12,50 +12,65 @@ using namespace std; #define CORE_EIGEN_ERROR_ORTHO 4 #define CORE_EIGEN_ERROR_ORDER 5 +#define MESSAGE_ERROR_COUNT "Matrix of eigen values must have the same rows as source matrix and 1 column." +#define MESSAGE_ERROR_SIZE "Source matrix and matrix of eigen vectors must have the same sizes." +#define MESSAGE_ERROR_DIFF_1 "Accurasy of eigen values computing less than required." +#define MESSAGE_ERROR_DIFF_2 "Accuracy of eigen vectors computing less than required." +#define MESSAGE_ERROR_ORTHO "Matrix of eigen vectors is not orthogonal." +#define MESSAGE_ERROR_ORDER "Eigen values are not sorted in ascending order." + +const size_t COUNT_NORM_TYPES = 3; +const size_t NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF}; + +enum TASK_TYPE_EIGEN {VALUES, VECTORS}; + class Core_EigenTest: public cvtest::BaseTest { - public: +public: - Core_EigenTest(); + Core_EigenTest(); ~Core_EigenTest(); - protected: +protected: - bool test_values(const cv::Mat& src); // complex test for eigen without vectors - bool check_full(int type); // compex test for symmetric matrix - virtual void run (int) = 0; // main testing method - - private: - - float eps_val_32, eps_vec_32; - float eps_val_64, eps_vec_64; - bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index = -1, int high_index = -1); - bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index = -1, int high_index = -1); - bool check_pairs_order(const cv::Mat& eigen_values); // checking order of eigen values & vectors (it should be none up) - bool check_orthogonality(const cv::Mat& U); // checking is matrix of eigen vectors orthogonal - bool test_pairs(const cv::Mat& src); // complex test for eigen with vectors + bool test_values(const cv::Mat& src); // complex test for eigen without vectors + bool check_full(int type); // compex test for symmetric matrix + virtual void run (int) = 0; // main testing method + +private: + + float eps_val_32, eps_vec_32; + float eps_val_64, eps_vec_64; + bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index = -1, int high_index = -1); + bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index = -1, int high_index = -1); + bool check_pairs_order(const cv::Mat& eigen_values); // checking order of eigen values & vectors (it should be none up) + bool check_orthogonality(const cv::Mat& U); // checking is matrix of eigen vectors orthogonal + bool test_pairs(const cv::Mat& src); // complex test for eigen with vectors + + void print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff); }; class Core_EigenTest_Scalar : public Core_EigenTest { - public: - Core_EigenTest_Scalar() : Core_EigenTest() {} - ~Core_EigenTest_Scalar(); - virtual void run(int) = 0; +public: + Core_EigenTest_Scalar() : Core_EigenTest() {} + ~Core_EigenTest_Scalar(); + + virtual void run(int) = 0; }; class Core_EigenTest_Scalar_32 : public Core_EigenTest_Scalar { - public: - Core_EigenTest_Scalar_32() : Core_EigenTest_Scalar() {} - ~Core_EigenTest_Scalar_32(); +public: + Core_EigenTest_Scalar_32() : Core_EigenTest_Scalar() {} + ~Core_EigenTest_Scalar_32(); - void run(int); + void run(int); }; class Core_EigenTest_Scalar_64 : public Core_EigenTest_Scalar { - public: +public: Core_EigenTest_Scalar_64() : Core_EigenTest_Scalar() {} ~Core_EigenTest_Scalar_64(); void run(int); @@ -63,7 +78,7 @@ class Core_EigenTest_Scalar_64 : public Core_EigenTest_Scalar class Core_EigenTest_32 : public Core_EigenTest { - public: +public: Core_EigenTest_32(): Core_EigenTest() {} ~Core_EigenTest_32() {} void run(int); @@ -71,10 +86,10 @@ class Core_EigenTest_32 : public Core_EigenTest class Core_EigenTest_64 : public Core_EigenTest { - public: - Core_EigenTest_64(): Core_EigenTest() {} - ~Core_EigenTest_64() {} - void run(int); +public: + Core_EigenTest_64(): Core_EigenTest() {} + ~Core_EigenTest_64() {} + void run(int); }; Core_EigenTest_Scalar::~Core_EigenTest_Scalar() {} @@ -83,18 +98,18 @@ Core_EigenTest_Scalar_64::~Core_EigenTest_Scalar_64() {} void Core_EigenTest_Scalar_32::run(int) { - float value = cv::randu(); - cv::Mat src(1, 1, CV_32FC1, Scalar::all((float)value)); - test_values(src); - src.~Mat(); + float value = cv::randu(); + cv::Mat src(1, 1, CV_32FC1, Scalar::all((float)value)); + test_values(src); + src.~Mat(); } void Core_EigenTest_Scalar_64::run(int) { - float value = cv::randu(); - cv::Mat src(1, 1, CV_64FC1, Scalar::all((double)value)); - test_values(src); - src.~Mat(); + float value = cv::randu(); + cv::Mat src(1, 1, CV_64FC1, Scalar::all((double)value)); + test_values(src); + src.~Mat(); } void Core_EigenTest_32::run(int) { check_full(CV_32FC1); } @@ -105,207 +120,245 @@ Core_EigenTest::~Core_EigenTest() {} bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index, int high_index) { - int n = src.rows, s = sign(high_index); - if (!( (evalues.rows == n - max(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)))) && (evalues.cols == 1))) - { - std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl; - CV_Error(CORE_EIGEN_ERROR_COUNT, "Matrix of eigen values must have the same rows as source matrix and 1 column."); - return false; - } - return true; + int n = src.rows, s = sign(high_index); + if (!( (evalues.rows == n - max(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)))) && (evalues.cols == 1))) + { + std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl; + std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl; + std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl; + CV_Error(CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return false; + } + return true; } bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index, int high_index) { - int n = src.rows, s = sign(high_index); - int right_eigen_pair_count = n - max(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1))); - - if (!((evectors.rows == right_eigen_pair_count) && (evectors.cols == right_eigen_pair_count))) - { - std::cout << "Checking sizes of eigen vectors matrix " << evectors << "..." << endl; - CV_Error (CORE_EIGEN_ERROR_SIZE, "Source matrix and matrix of eigen vectors must have the same sizes."); - return false; - } - - if (!((evalues.rows == right_eigen_pair_count) && (evalues.cols == 1))) - { - std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl; - CV_Error (CORE_EIGEN_ERROR_COUNT, "Matrix of eigen values must have the same rows as source matrix and 1 column."); - return false; - } - - return true; + int n = src.rows, s = sign(high_index); + int right_eigen_pair_count = n - max(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1))); + + if (!((evectors.rows == right_eigen_pair_count) && (evectors.cols == right_eigen_pair_count))) + { + std::cout << endl; std::cout << "Checking sizes of eigen vectors matrix " << evectors << "..." << endl; + std::cout << "Number of rows: " << evectors.rows << " Number of cols: " << evectors.cols << endl; + std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl; + CV_Error (CORE_EIGEN_ERROR_SIZE, MESSAGE_ERROR_SIZE); + return false; + } + + if (!((evalues.rows == right_eigen_pair_count) && (evalues.cols == 1))) + { + std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl; + std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl; + std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl; + CV_Error (CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT); + return false; + } + + return true; } -bool Core_EigenTest::check_orthogonality(const cv::Mat& U) +void Core_EigenTest::print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff) { - int type = U.type(); - double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64; - cv::Mat UUt; cv::mulTransposed(U, UUt, false); - - cv::Mat E = Mat::eye(U.rows, U.cols, type); - - double diff_L1 = cv::norm(UUt, E, NORM_L1); - double diff_L2 = cv::norm(UUt, E, NORM_L2); - double diff_INF = cv::norm(UUt, E, NORM_INF); - - if (diff_L1 > eps_vec) { std::cout << "Checking orthogonality of matrix " << U << "..." << endl; CV_Error(CORE_EIGEN_ERROR_ORTHO, "Matrix of eigen vectors is not orthogonal."); return false; } - if (diff_L2 > eps_vec) { std::cout << "Checking orthogonality of matrix " << U << "..." << endl; CV_Error(CORE_EIGEN_ERROR_ORTHO, "Matrix of eigen vectors is not orthogonal."); return false; } - if (diff_INF > eps_vec) { std::cout << "Checking orthogonality of matrix " << U << "..." << endl; CV_Error(CORE_EIGEN_ERROR_ORTHO, "Matrix of eigen vectors is not orthogonal."); return false; } + switch (NORM_TYPE[norm_idx]) + { + case cv::NORM_L1: {std::cout << "L1"; break;} + case cv::NORM_L2: {std::cout << "L2"; break;} + case cv::NORM_INF: {std::cout << "INF"; break;} + default: break; + } + + cout << "-criteria... " << endl; + cout << "Source size: " << src.rows << " * " << src.cols << endl; + cout << "Difference between original eigen vectors matrix and result: " << diff << endl; + cout << "Maximum allowed difference: " << max_diff << endl; cout << endl; +} - return true; +bool Core_EigenTest::check_orthogonality(const cv::Mat& U) +{ + int type = U.type(); + double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64; + cv::Mat UUt; cv::mulTransposed(U, UUt, false); + + cv::Mat E = Mat::eye(U.rows, U.cols, type); + + for (size_t i = 0; i < COUNT_NORM_TYPES; ++i) + { + double diff = cv::norm(UUt, E, NORM_TYPE[i]); + if (diff > eps_vec) + { + std::cout << endl; std::cout << "Checking orthogonality of matrix " << U << ": "; + print_information(i, U, diff, eps_vec); + CV_Error(CORE_EIGEN_ERROR_ORTHO, MESSAGE_ERROR_ORTHO); + return false; + } + } + + return true; } bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values) { - switch (eigen_values.type()) - { - case CV_32FC1: - { - for (int i = 0; i < eigen_values.total() - 1; ++i) - if (!(eigen_values.at(i, 0) > eigen_values.at(i+1, 0))) - { - std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl; - CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in ascending order."); - return false; - } - - break; - } - - case CV_64FC1: - { - for (int i = 0; i < eigen_values.total() - 1; ++i) - if (!(eigen_values.at(i, 0) > eigen_values.at(i+1, 0))) - { - std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl; - CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in ascending order."); - return false; - } - - break; - } - - default:; - } - - return true; + switch (eigen_values.type()) + { + case CV_32FC1: + { + for (size_t i = 0; i < eigen_values.total() - 1; ++i) + if (!(eigen_values.at(i, 0) > eigen_values.at(i+1, 0))) + { + std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl; + std::cout << "Pair of indexes with non ascending of eigen values: (" << i << ", " << i+1 << ")." << endl; + std::cout << endl; + CV_Error(CORE_EIGEN_ERROR_ORDER, MESSAGE_ERROR_ORDER); + return false; + } + + break; + } + + case CV_64FC1: + { + for (size_t i = 0; i < eigen_values.total() - 1; ++i) + if (!(eigen_values.at(i, 0) > eigen_values.at(i+1, 0))) + { + std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl; + std::cout << "Pair of indexes with non ascending of eigen values: (" << i << ", " << i+1 << ")." << endl; + std::cout << endl; + CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in ascending order."); + return false; + } + + break; + } + + default:; + } + + return true; } bool Core_EigenTest::test_pairs(const cv::Mat& src) { - int type = src.type(); - double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64; + int type = src.type(); + double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64; + + cv::Mat eigen_values, eigen_vectors; - cv::Mat eigen_values, eigen_vectors; - - cv::eigen(src, true, eigen_values, eigen_vectors); + cv::eigen(src, true, eigen_values, eigen_vectors); - if (!check_pair_count(src, eigen_values, eigen_vectors)) return false; + if (!check_pair_count(src, eigen_values, eigen_vectors)) return false; - if (!check_orthogonality (eigen_vectors)) return false; + if (!check_orthogonality (eigen_vectors)) return false; - if (!check_pairs_order(eigen_values)) return false; + if (!check_pairs_order(eigen_values)) return false; - cv::Mat eigen_vectors_t; cv::transpose(eigen_vectors, eigen_vectors_t); + cv::Mat eigen_vectors_t; cv::transpose(eigen_vectors, eigen_vectors_t); - cv::Mat src_evec(src.rows, src.cols, type); - src_evec = src*eigen_vectors_t; + cv::Mat src_evec(src.rows, src.cols, type); + src_evec = src*eigen_vectors_t; - cv::Mat eval_evec(src.rows, src.cols, type); + cv::Mat eval_evec(src.rows, src.cols, type); - switch (type) - { - case CV_32FC1: - { - for (size_t i = 0; i < src.cols; ++i) - { - cv::Mat tmp = eigen_values.at(i, 0) * eigen_vectors_t.col(i); - for (size_t j = 0; j < src.rows; ++j) eval_evec.at(j, i) = tmp.at(j, 0); - } + switch (type) + { + case CV_32FC1: + { + for (int i = 0; i < src.cols; ++i) + { + cv::Mat tmp = eigen_values.at(i, 0) * eigen_vectors_t.col(i); + for (int j = 0; j < src.rows; ++j) eval_evec.at(j, i) = tmp.at(j, 0); + } - break; - } - - case CV_64FC1: - { - for (size_t i = 0; i < src.cols; ++i) - { - cv::Mat tmp = eigen_values.at(i, 0) * eigen_vectors_t.col(i); - for (size_t j = 0; j < src.rows; ++j) eval_evec.at(j, i) = tmp.at(j, 0); - } + break; + } - break; - } + case CV_64FC1: + { + for (int i = 0; i < src.cols; ++i) + { + cv::Mat tmp = eigen_values.at(i, 0) * eigen_vectors_t.col(i); + for (int j = 0; j < src.rows; ++j) eval_evec.at(j, i) = tmp.at(j, 0); + } - default:; - } + break; + } - cv::Mat disparity = src_evec - eval_evec; + default:; + } - double diff_L1 = cv::norm(disparity, NORM_L1); - double diff_L2 = cv::norm(disparity, NORM_L2); - double diff_INF = cv::norm(disparity, NORM_INF); + cv::Mat disparity = src_evec - eval_evec; - if (diff_L1 > eps_vec) { std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": L1-criteria..." << endl; CV_Error(CORE_EIGEN_ERROR_DIFF, "Accuracy of eigen vectors computing less than required."); return false; } - if (diff_L2 > eps_vec) { std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": L2-criteria..." << endl; CV_Error(CORE_EIGEN_ERROR_DIFF, "Accuracy of eigen vectors computing less than required."); return false; } - if (diff_INF > eps_vec) { std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": INF-criteria..." << endl; CV_Error(CORE_EIGEN_ERROR_DIFF, "Accuracy of eigen vectors computing less than required."); return false; } + for (size_t i = 0; i < COUNT_NORM_TYPES; ++i) + { + double diff = cv::norm(disparity, NORM_TYPE[i]); + if (diff > eps_vec) + { + std::cout << endl; std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": "; + print_information(i, src, diff, eps_vec); + CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_2); + return false; + } + } - return true; + return true; } bool Core_EigenTest::test_values(const cv::Mat& src) { - int type = src.type(); - double eps_val = type == CV_32FC1 ? eps_val_32 : eps_val_64; + int type = src.type(); + double eps_val = type == CV_32FC1 ? eps_val_32 : eps_val_64; - cv::Mat eigen_values_1, eigen_values_2, eigen_vectors; + cv::Mat eigen_values_1, eigen_values_2, eigen_vectors; - if (!test_pairs(src)) return false; + if (!test_pairs(src)) return false; - cv::eigen(src, true, eigen_values_1, eigen_vectors); - cv::eigen(src, false, eigen_values_2, eigen_vectors); + cv::eigen(src, true, eigen_values_1, eigen_vectors); + cv::eigen(src, false, eigen_values_2, eigen_vectors); - if (!check_pair_count(src, eigen_values_2)) return false; + if (!check_pair_count(src, eigen_values_2)) return false; - double diff_L1 = cv::norm(eigen_values_1, eigen_values_2, NORM_L1); - double diff_L2 = cv::norm(eigen_values_1, eigen_values_2, NORM_L2); - double diff_INF = cv::norm(eigen_values_1, eigen_values_2, NORM_INF); - - if (diff_L1 > eps_val) { std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": L1-criteria..." << endl; CV_Error(CORE_EIGEN_ERROR_DIFF, "Accuracy of eigen values computing less than required."); return false; } - if (diff_L2 > eps_val) { std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": L2-criteria..." << endl; CV_Error(CORE_EIGEN_ERROR_DIFF, "Accuracy of eigen vectors computing less than required."); return false; } - if (diff_INF > eps_val) { std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": INF-criteria..." << endl; CV_Error(CORE_EIGEN_ERROR_DIFF, "Accuracy of eigen vectors computing less than required."); return false; } + for (size_t i = 0; i < COUNT_NORM_TYPES; ++i) + { + double diff = cv::norm(eigen_values_1, eigen_values_2, NORM_TYPE[i]); + if (diff > eps_val) + { + std::cout << endl; std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": "; + print_information(i, src, diff, eps_val); + CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_1); + return false; + } + } - return true; + return true; } bool Core_EigenTest::check_full(int type) { - const int MATRIX_COUNT = 500; - const int MAX_DEGREE = 7; + const int MATRIX_COUNT = 500; + const int MAX_DEGREE = 7; + + srand(time(0)); + + for (int i = 1; i <= MATRIX_COUNT; ++i) + { + size_t src_size = (int)(std::pow(2.0, (rand()%MAX_DEGREE+1)*1.0)); - srand(time(0)); + cv::Mat src(src_size, src_size, type); - for (size_t i = 1; i <= MATRIX_COUNT; ++i) - { - size_t src_size = (int)(std::pow(2.0, (rand()%MAX_DEGREE+1)*1.0)); - - cv::Mat src(src_size, src_size, type); + for (int j = 0; j < src.rows; ++j) + for (int k = j; k < src.cols; ++k) + if (type == CV_32FC1) src.at(k, j) = src.at(j, k) = cv::randu(); + else src.at(k, j) = src.at(j, k) = cv::randu(); - for (int j = 0; j < src.rows; ++j) - for (int k = j; k < src.cols; ++k) - if (type == CV_32FC1) src.at(k, j) = src.at(j, k) = cv::randu(); - else src.at(k, j) = src.at(j, k) = cv::randu(); - - if (!test_values(src)) return false; + if (!test_values(src)) return false; - src.~Mat(); - } + src.~Mat(); + } - return true; + return true; } -// TEST(Core_Eigen_Scalar_32, single_complex) {Core_EigenTest_Scalar_32 test; test.safe_run(); } -// TEST(Core_Eigen_Scalar_64, single_complex) {Core_EigenTest_Scalar_64 test; test.safe_run(); } -TEST(Core_Eigen_32, complex) { Core_EigenTest_32 test; test.safe_run(); } -TEST(Core_Eigen_64, complex) { Core_EigenTest_64 test; test.safe_run(); } \ No newline at end of file +// TEST(Core_Eigen_Scalar_32, accuracy) {Core_EigenTest_Scalar_32 test; test.safe_run(); } +// TEST(Core_Eigen_Scalar_64, accuracy) {Core_EigenTest_Scalar_64 test; test.safe_run(); } +TEST(Core_Eigen_32, accuracy) { Core_EigenTest_32 test; test.safe_run(); } +TEST(Core_Eigen_64, accuracy) { Core_EigenTest_64 test; test.safe_run(); } diff --git a/modules/imgproc/test/test_boundingrect.cpp b/modules/imgproc/test/test_boundingrect.cpp index cf29d2e9fd..bbb8936990 100644 --- a/modules/imgproc/test/test_boundingrect.cpp +++ b/modules/imgproc/test/test_boundingrect.cpp @@ -1,6 +1,5 @@ #include "test_precomp.hpp" #include -#include #define IMGPROC_BOUNDINGRECT_ERROR_DIFF 1 @@ -11,94 +10,93 @@ using namespace std; class CV_BoundingRectTest: public cvtest::ArrayTest { - public: +public: CV_BoundingRectTest(); ~CV_BoundingRectTest(); - protected: +protected: void run (int); - private: - template void generate_src_points(vector >& src, int n); - template cv::Rect get_bounding_rect(const vector > src); - template bool checking_function_work(vector >& src, int type); +private: + template void generate_src_points(vector >& src, int n); + template cv::Rect get_bounding_rect(const vector > src); + template bool checking_function_work(vector >& src, int type); }; CV_BoundingRectTest::CV_BoundingRectTest() {} CV_BoundingRectTest::~CV_BoundingRectTest() {} -template void CV_BoundingRectTest::generate_src_points(vector >& src, int n) +template void CV_BoundingRectTest::generate_src_points(vector >& src, int n) { - src.clear(); - for (size_t i = 0; i < n; ++i) - src.push_back(Point_(cv::randu(), cv::randu())); + src.clear(); + for (int i = 0; i < n; ++i) + src.push_back(Point_(cv::randu(), cv::randu())); } -template cv::Rect CV_BoundingRectTest::get_bounding_rect(const vector > src) +template cv::Rect CV_BoundingRectTest::get_bounding_rect(const vector > src) { - int n = src.size(); - T min_w = std::numeric_limits::max(), max_w = std::numeric_limits::min(); - T min_h = min_w, max_h = max_w; - - for (size_t i = 0; i < n; ++i) - { - min_w = std::min(src.at(i).x, min_w); - max_w = std::max(src.at(i).x, max_w); - min_h = std::min(src.at(i).y, min_h); - max_h = std::max(src.at(i).y, max_h); - } - - return Rect((int)min_w, (int)min_h, (int)(floor(1.0*(max_w-min_w)) + 1), (int)(floor(1.0*(max_h-min_h)) + 1)); + int n = src.size(); + T min_w = std::numeric_limits::max(), max_w = std::numeric_limits::min(); + T min_h = min_w, max_h = max_w; + + for (int i = 0; i < n; ++i) + { + min_w = std::min(src.at(i).x, min_w); + max_w = std::max(src.at(i).x, max_w); + min_h = std::min(src.at(i).y, min_h); + max_h = std::max(src.at(i).y, max_h); + } + + return Rect((int)min_w, (int)min_h, (int)(floor(1.0*(max_w-min_w)) + 1), (int)(floor(1.0*(max_h-min_h)) + 1)); } -template bool CV_BoundingRectTest::checking_function_work(vector >& src, int type) +template bool CV_BoundingRectTest::checking_function_work(vector >& src, int type) { - const int MAX_COUNT_OF_POINTS = 1000; - const int N = 10000; - - for (int k = 0; k < N; ++k) - { - - RNG& rng = ts->get_rng(); - - int n = rng.next()%MAX_COUNT_OF_POINTS + 1; - - generate_src_points (src, n); - - cv::Rect right = get_bounding_rect (src); - - cv::Rect rect[2] = { boundingRect(src), boundingRect(Mat(src)) }; - - for (int i = 0; i < 2; ++i) if (rect[i] != right) - { - cout << endl; cout << "Checking for the work of boundingRect function..." << endl; - cout << "Type of src points: "; - switch (type) - { - case 0: {cout << "INT"; break;} - case 1: {cout << "FLOAT"; break;} - case 2: {cout << "DOUBLE"; break;} - default: break; - } - cout << endl; - cout << "Src points are stored as "; if (i == 0) cout << "VECTOR" << endl; else cout << "MAT" << endl; - cout << "Number of points: " << n << endl; - cout << "Right rect (x, y, w, h): [" << right.x << ", " << right.y << ", " << right.width << ", " << right.height << "]" << endl; - cout << "Result rect (x, y, w, h): [" << rect[i].x << ", " << rect[i].y << ", " << rect[i].width << ", " << rect[i].height << "]" << endl; - cout << endl; - CV_Error(IMGPROC_BOUNDINGRECT_ERROR_DIFF, MESSAGE_ERROR_DIFF); - return false; - } - - } - - return true; + const int MAX_COUNT_OF_POINTS = 1000; + const int N = 10000; + + for (int k = 0; k < N; ++k) + { + + RNG& rng = ts->get_rng(); + + int n = rng.next()%MAX_COUNT_OF_POINTS + 1; + + generate_src_points (src, n); + + cv::Rect right = get_bounding_rect (src); + + cv::Rect rect[2] = { boundingRect(src), boundingRect(Mat(src)) }; + + for (int i = 0; i < 2; ++i) if (rect[i] != right) + { + cout << endl; cout << "Checking for the work of boundingRect function..." << endl; + cout << "Type of src points: "; + switch (type) + { + case 0: {cout << "INT"; break;} + case 1: {cout << "FLOAT"; break;} + default: break; + } + cout << endl; + cout << "Src points are stored as "; if (i == 0) cout << "VECTOR" << endl; else cout << "MAT" << endl; + cout << "Number of points: " << n << endl; + cout << "Right rect (x, y, w, h): [" << right.x << ", " << right.y << ", " << right.width << ", " << right.height << "]" << endl; + cout << "Result rect (x, y, w, h): [" << rect[i].x << ", " << rect[i].y << ", " << rect[i].width << ", " << rect[i].height << "]" << endl; + cout << endl; + CV_Error(IMGPROC_BOUNDINGRECT_ERROR_DIFF, MESSAGE_ERROR_DIFF); + return false; + } + + } + + return true; } void CV_BoundingRectTest::run(int) { - vector src_veci; if (!checking_function_work(src_veci, 0)) return; - vector src_vecf; checking_function_work(src_vecf, 1); + vector src_veci; if (!checking_function_work(src_veci, 0)) return; + vector src_vecf; checking_function_work(src_vecf, 1); } -TEST (Imgproc_BoundingRect, accuracy) { CV_BoundingRectTest test; test.safe_run(); } \ No newline at end of file +TEST (Imgproc_BoundingRect, accuracy) { CV_BoundingRectTest test; test.safe_run(); } -- GitLab