From 4cfc9dc67e6830aa0a46f935541ecbea869ce7c8 Mon Sep 17 00:00:00 2001 From: Alexander Reshetnikov Date: Fri, 23 Dec 2011 18:36:04 +0000 Subject: [PATCH] fixed bag in the checking size of matrix and vector for eigen test; all eigen test execution was checked: it works correctly; added first version of homography test for C++ interface --- modules/calib3d/test/test_homography.cpp | 88 ++++++++++++++++++++++++++++++++ modules/core/test/test_eigen.cpp | 56 ++++++++++---------- 2 files changed, 117 insertions(+), 27 deletions(-) create mode 100644 modules/calib3d/test/test_homography.cpp diff --git a/modules/calib3d/test/test_homography.cpp b/modules/calib3d/test/test_homography.cpp new file mode 100644 index 0000000..c264c47 --- /dev/null +++ b/modules/calib3d/test/test_homography.cpp @@ -0,0 +1,88 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +class CV_HomographyTest: public cvtest::BaseTest +{ + public: + + CV_HomographyTest(); + ~CV_HomographyTest(); + + protected: + + void run (int); + + private: + float max_diff; + void check_matrix_size(const cv::Mat& H); + void check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type = NORM_L2); + 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-5) {} +CV_HomographyTest::~CV_HomographyTest() {} + +void CV_HomographyTest::check_matrix_size(const cv::Mat& H) +{ + CV_Assert ( H.rows == 3 && H.cols == 3); +} + +void CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type) +{ + double diff = cv::norm(original, found, norm_type); + CV_Assert ( diff <= max_diff ); +} + +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 ); +} + +void CV_HomographyTest::run(int) +{ + // test data without outliers + cv::Vec3f n_src(1.0f, 1.0f, 1.0f), n_dst(1.0f, -1.0f, 0.0f); + const float d_src = 1.0f, d_dst = 0.0f; + const int n_points = 100; + + float P[2*n_points], Q[2*n_points]; + + for (size_t i = 0; i < 2*n_points; i += 2) + { + float u1 = cv::randu(), v1 = cv::randu(); + float w1 = 1.0f/(d_src - n_src[0]*u1 - n_src[1]*v1); + P[i] = u1*w1; P[i+1] = v1*w1; + + float u2 = cv::randu(), v2 = cv::randu(); + float w2 = 1.0f/(d_src - n_src[0]*u1 - n_src[1]*v1); + Q[i] = u2*w2; Q[i+1] = v2*w2; + } + + cv::Mat src(n_points, 1, CV_32FC2, P); + cv::Mat dst(n_points, 1, CV_32FC2, Q); + + cv::Mat H = cv::findHomography(src, dst); + + check_matrix_size(H); + + // check_transform_quality(src, dst, H, NORM_L1); + + // check_matrix_diff(_H, H, NORM_L1); +} + +TEST(Core_Homography, complex_test) { CV_HomographyTest test; test.safe_run(); } \ No newline at end of file diff --git a/modules/core/test/test_eigen.cpp b/modules/core/test/test_eigen.cpp index ad29297..f982199 100644 --- a/modules/core/test/test_eigen.cpp +++ b/modules/core/test/test_eigen.cpp @@ -3,7 +3,7 @@ using namespace cv; using namespace std; -#define sign(a) a > 0 ? 1 : a < 0 ? 0 : -1 +#define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1 class Core_EigenTest: public cvtest::BaseTest { @@ -25,23 +25,23 @@ class Core_EigenTest: public cvtest::BaseTest const bool compute_eigen_vectors, const int values_type, const int norm_type); }; -Core_EigenTest::Core_EigenTest() : eps_val_32(1e-6), eps_vec_32(1e-5), eps_val_64(1e-12), eps_vec_64(1e-11) {} +Core_EigenTest::Core_EigenTest() : eps_val_32(1e-3), eps_vec_32(1e-2), eps_val_64(1e-5), eps_vec_64(1e-4) {} Core_EigenTest::~Core_EigenTest() {} void 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); - CV_Assert(evalues.rows == n - (low_index+1) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1))) && evalues.cols == 1); + CV_Assert ( 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); } void 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 - (low_index+1) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1))); - CV_Assert( evectors.rows == right_eigen_pair_count && - evectors.cols == right_eigen_pair_count && - evalues.rows == right_eigen_pair_count && - evalues.cols == 1); + 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))); + CV_Assert ( evectors.rows == right_eigen_pair_count && + evectors.cols == right_eigen_pair_count && + evalues.rows == right_eigen_pair_count && + evalues.cols == 1 ); } bool Core_EigenTest::check_diff(const cv::Mat& original_values, const cv::Mat& original_vectors, @@ -85,23 +85,23 @@ void Core_EigenTest::run(int) // tests data - float sym_matrix[DIM][DIM] = { { 0.0f, 1.0f, 0.0f }, - { 1.0f, 0.0f, 1.0f }, - { 0.0f, 1.0f, 0.0f } }; // source symmerical matrix + float sym_matrix[DIM*DIM] = { 0.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 0.0f }; // source symmerical matrix - float _eval[DIM] = { sqrt(2.0f), 0.0f, -sqrt(2.0f) }; // eigen values of 3*3 matrix + float _eval[DIM] = { sqrt(2.0f), 0.0f, -sqrt(2.0f) }; // eigen values of 3*3 matrix - float _evec[DIM][DIM] = { { 1.0f, sqrt(2.0f), 1.0f }, - { -1.0f, 0.0f, 1.0f }, - { 1.0f, -sqrt(2.0f), 1.0f } }; // eigen vectors of source matrix + float _evec[DIM*DIM] = { 0.5f, 0.5f*sqrt(2.0f), 0.5f, + -0.5f*sqrt(2.0f), 0.0f, 0.5f*sqrt(2.0f), + 0.5f, -0.5f*sqrt(2.0f), 0.5f }; // eigen vectors of source matrix // initializing Mat-objects cv::Mat eigen_values, eigen_vectors; - cv::Mat src_32(DIM, DIM, CV_32FC1, (void*)&sym_matrix[0]); - cv::Mat eval_32(DIM, 1, CV_32FC1, (void*)&_eval); - cv::Mat evec_32(DIM, DIM, CV_32FC1, (void*)&_evec[0]); + cv::Mat src_32(DIM, DIM, CV_32FC1, sym_matrix); + cv::Mat eval_32(DIM, 1, CV_32FC1, _eval); + cv::Mat evec_32(DIM, DIM, CV_32FC1, _evec); cv::eigen(src_32, true, eigen_values, eigen_vectors); @@ -134,13 +134,15 @@ void Core_EigenTest::run(int) if (!check_diff(eval_32, evec_32, eigen_values, eigen_vectors, false, CV_32FC1, NORM_L1)) return; if (!check_diff(eval_32, evec_32, eigen_values, eigen_vectors, false, CV_32FC1, NORM_L2)) return; if (!check_diff(eval_32, evec_32, eigen_values, eigen_vectors, false, CV_32FC1, NORM_INF)) return; - - cv::Mat src_64(DIM, DIM, CV_64FC1, (void*)&sym_matrix[0]); - cv::Mat eval_64(DIM, 1, CV_64FC1, (void*)&_eval); - cv::Mat evec_64(DIM, DIM, CV_64FC1, (void*)&_evec[0]); + + cv::Mat src_64(DIM, DIM, CV_64FC1, sym_matrix); + cv::Mat eval_64(DIM, 1, CV_64FC1, _eval); + cv::Mat evec_64(DIM, DIM, CV_64FC1, _evec); cv::eigen(src_64, true, eigen_values, eigen_vectors); + check_pair_count(src_64, eigen_values, eigen_vectors); + if (!check_diff(eval_64, evec_64, eigen_values, eigen_vectors, true, CV_64FC1, NORM_L1)) return; if (!check_diff(eval_64, evec_64, eigen_values, eigen_vectors, true, CV_64FC1, NORM_L2)) return; if (!check_diff(eval_64, evec_64, eigen_values, eigen_vectors, true, CV_64FC1, NORM_INF)) return; @@ -169,12 +171,12 @@ void Core_EigenTest::run(int) if (!check_diff(eval_64, evec_64, eigen_values, eigen_vectors, false, CV_64FC1, NORM_L2)) return; if (!check_diff(eval_64, evec_64, eigen_values, eigen_vectors, false, CV_64FC1, NORM_INF)) return; - const int low_index = 2, high_index = 3; + const int low_index = 1, high_index = 2; cv::Mat submat_val_32(eval_32.rowRange(low_index, high_index)); cv::Mat submat_vec_32(evec_32.rowRange(low_index, high_index)); - cv::eigen(src_32, eigen_values, low_index, high_index); - + cv::eigen(src_32, eigen_values, low_index, high_index); + check_pair_count(src_32, eigen_values, eigen_vectors, low_index, high_index); if (!check_diff(submat_val_32, submat_vec_32, eigen_values, eigen_vectors, false, CV_32FC1, NORM_L1)) return; @@ -188,7 +190,7 @@ void Core_EigenTest::run(int) if (!check_diff(submat_val_32, submat_vec_32, eigen_values, eigen_vectors, true, CV_32FC1, NORM_L1)) return; if (!check_diff(submat_val_32, submat_vec_32, eigen_values, eigen_vectors, true, CV_32FC1, NORM_L2)) return; if (!check_diff(submat_val_32, submat_vec_32, eigen_values, eigen_vectors, true, CV_32FC1, NORM_INF)) return; - + cv::Mat submat_val_64(eval_64.rowRange(low_index, high_index)); cv::Mat submat_vec_64(evec_64.rowRange(low_index, high_index)); @@ -209,5 +211,5 @@ void Core_EigenTest::run(int) if (!check_diff(submat_val_64, submat_vec_64, eigen_values, eigen_vectors, true, CV_64FC1, NORM_INF)) return; } -TEST(Core_Eigen, quality) { Core_EigenTest test; test.safe_run(); } +TEST(Core_Eigen, accuracy) { Core_EigenTest test; test.safe_run(); } -- 2.7.4