1 /*M///////////////////////////////////////////////////////////////////////////////////////
\r
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
\r
5 // By downloading, copying, installing or using the software you agree to this license.
\r
6 // If you do not agree to this license, do not download, install,
\r
7 // copy or use the software.
\r
10 // License Agreement
\r
11 // For Open Source Computer Vision Library
\r
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
\r
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
\r
15 // Third party copyrights are property of their respective owners.
\r
17 // Redistribution and use in source and binary forms, with or without modification,
\r
18 // are permitted provided that the following conditions are met:
\r
20 // * Redistribution's of source code must retain the above copyright notice,
\r
21 // this list of conditions and the following disclaimer.
\r
23 // * Redistribution's in binary form must reproduce the above copyright notice,
\r
24 // this list of conditions and the following disclaimer in the documentation
\r
25 // and/or other materials provided with the distribution.
\r
27 // * The name of the copyright holders may not be used to endorse or promote products
\r
28 // derived from this software without specific prior written permission.
\r
30 // This software is provided by the copyright holders and contributors "as is" and
\r
31 // any express or implied warranties, including, but not limited to, the implied
\r
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
\r
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
\r
34 // indirect, incidental, special, exemplary, or consequential damages
\r
35 // (including, but not limited to, procurement of substitute goods or services;
\r
36 // loss of use, data, or profits; or business interruption) however caused
\r
37 // and on any theory of liability, whether in contract, strict liability,
\r
38 // or tort (including negligence or otherwise) arising in any way out of
\r
39 // the use of this software, even if advised of the possibility of such damage.
\r
43 #include "test_precomp.hpp"
\r
46 #define CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE 1
\r
47 #define CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF 2
\r
48 #define CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF 3
\r
49 #define CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK 4
\r
50 #define CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF 5
\r
52 #define MESSAGE_MATRIX_SIZE "Homography matrix must have 3*3 sizes."
\r
53 #define MESSAGE_MATRIX_DIFF "Accuracy of homography transformation matrix less than required."
\r
54 #define MESSAGE_REPROJ_DIFF_1 "Reprojection error for current pair of points more than required."
\r
55 #define MESSAGE_REPROJ_DIFF_2 "Reprojection error is not optimal."
\r
56 #define MESSAGE_RANSAC_MASK_1 "Sizes of inliers/outliers mask are incorrect."
\r
57 #define MESSAGE_RANSAC_MASK_2 "Mask mustn't have any outliers."
\r
58 #define MESSAGE_RANSAC_MASK_3 "All values of mask must be 1 (true) or 0 (false)."
\r
59 #define MESSAGE_RANSAC_MASK_4 "Mask of inliers/outliers is incorrect."
\r
60 #define MESSAGE_RANSAC_MASK_5 "Inlier in original mask shouldn't be outlier in found mask."
\r
61 #define MESSAGE_RANSAC_DIFF "Reprojection error for current pair of points more than required."
\r
63 #define MAX_COUNT_OF_POINTS 303
\r
64 #define COUNT_NORM_TYPES 3
\r
65 #define METHODS_COUNT 3
\r
67 size_t NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF};
\r
68 size_t METHOD[METHODS_COUNT] = {0, CV_RANSAC, CV_LMEDS};
\r
71 using namespace std;
\r
73 class CV_HomographyTest: public cvtest::ArrayTest
\r
76 CV_HomographyTest();
\r
77 ~CV_HomographyTest();
\r
85 double reproj_threshold;
\r
89 float max_diff, max_2diff;
\r
90 bool check_matrix_size(const cv::Mat& H);
\r
91 bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff);
\r
92 int check_ransac_mask_1(const Mat& src, const Mat& mask);
\r
93 int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask);
\r
95 void print_information_1(int j, int N, int method, const Mat& H);
\r
96 void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);
\r
97 void print_information_3(int j, int N, const Mat& mask);
\r
98 void print_information_4(int method, int j, int N, int k, int l, double diff);
\r
99 void print_information_5(int method, int j, int N, int l, double diff);
\r
100 void print_information_6(int j, int N, int k, double diff, bool value);
\r
101 void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value);
\r
102 void print_information_8(int j, int N, int k, int l, double diff);
\r
105 CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2), max_2diff(2e-2)
\r
109 reproj_threshold = 3.0;
\r
113 CV_HomographyTest::~CV_HomographyTest() {}
\r
115 bool CV_HomographyTest::check_matrix_size(const cv::Mat& H)
\r
117 return (H.rows == 3) && (H.cols == 3);
\r
120 bool CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff)
\r
122 diff = cv::norm(original, found, norm_type);
\r
123 return diff <= max_diff;
\r
126 int CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask)
\r
128 if (!(mask.cols == 1) && (mask.rows == src.cols)) return 1;
\r
129 if (countNonZero(mask) < mask.rows) return 2;
\r
130 for (int i = 0; i < mask.rows; ++i) if (mask.at<uchar>(i, 0) > 1) return 3;
\r
134 int CV_HomographyTest::check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask)
\r
136 if (!(found_mask.cols == 1) && (found_mask.rows == original_mask.rows)) return 1;
\r
137 for (int i = 0; i < found_mask.rows; ++i) if (found_mask.at<uchar>(i, 0) > 1) return 2;
\r
141 void CV_HomographyTest::print_information_1(int j, int N, int method, const Mat& H)
\r
143 cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
\r
144 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
145 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
146 cout << "Count of points: " << N << endl; cout << endl;
\r
147 cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
\r
148 cout << "Homography matrix:" << endl; cout << endl;
\r
149 cout << H << endl; cout << endl;
\r
150 cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl;
\r
153 void CV_HomographyTest::print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff)
\r
155 cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl;
\r
156 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
157 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
158 cout << "Count of points: " << N << endl; cout << endl;
\r
159 cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
\r
160 cout << "Original matrix:" << endl; cout << endl;
\r
161 cout << H << endl; cout << endl;
\r
162 cout << "Found matrix:" << endl; cout << endl;
\r
163 cout << H_res << endl; cout << endl;
\r
164 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;
\r
165 cout << "Difference between matrices: " << diff << endl;
\r
166 cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
\r
169 void CV_HomographyTest::print_information_3(int j, int N, const Mat& mask)
\r
171 cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
\r
172 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
173 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
174 cout << "Count of points: " << N << endl; cout << endl;
\r
175 cout << "Method: RANSAC" << endl;
\r
176 cout << "Found mask:" << endl; cout << endl;
\r
177 cout << mask << endl; cout << endl;
\r
178 cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl;
\r
181 void CV_HomographyTest::print_information_4(int method, int j, int N, int k, int l, double diff)
\r
183 cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;
\r
184 cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
\r
185 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
186 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
187 cout << "Sigma of normal noise: " << sigma << endl;
\r
188 cout << "Count of points: " << N << endl;
\r
189 cout << "Number of point: " << k << endl;
\r
190 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;
\r
191 cout << "Difference with noise of point: " << diff << endl;
\r
192 cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl;
\r
195 void CV_HomographyTest::print_information_5(int method, int j, int N, int l, double diff)
\r
197 cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;
\r
198 cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
\r
199 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
200 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
201 cout << "Sigma of normal noise: " << sigma << endl;
\r
202 cout << "Count of points: " << N << endl;
\r
203 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;
\r
204 cout << "Difference with noise of points: " << diff << endl;
\r
205 cout << "Maxumum allowed difference: " << max_diff << endl; cout << endl;
\r
208 void CV_HomographyTest::print_information_6(int j, int N, int k, double diff, bool value)
\r
210 cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
\r
211 cout << "Method: RANSAC" << endl;
\r
212 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
213 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
214 cout << "Count of points: " << N << " " << endl;
\r
215 cout << "Number of point: " << k << " " << endl;
\r
216 cout << "Reprojection error for this point: " << diff << " " << endl;
\r
217 cout << "Reprojection error threshold: " << reproj_threshold << " " << endl;
\r
218 cout << "Value of found mask: "<< value << endl; cout << endl;
\r
221 void CV_HomographyTest::print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value)
\r
223 cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
\r
224 cout << "Method: RANSAC" << endl;
\r
225 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
226 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
227 cout << "Count of points: " << N << " " << endl;
\r
228 cout << "Number of point: " << k << " " << endl;
\r
229 cout << "Reprojection error for this point: " << diff << " " << endl;
\r
230 cout << "Reprojection error threshold: " << reproj_threshold << " " << endl;
\r
231 cout << "Value of original mask: "<< original_value << " Value of found mask: " << found_value << endl; cout << endl;
\r
234 void CV_HomographyTest::print_information_8(int j, int N, int k, int l, double diff)
\r
236 cout << endl; cout << "Checking for reprojection error of inlier..." << endl; cout << endl;
\r
237 cout << "Method: RANSAC" << endl;
\r
238 cout << "Sigma of normal noise: " << sigma << endl;
\r
239 cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
\r
240 cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
\r
241 cout << "Count of points: " << N << " " << endl;
\r
242 cout << "Number of point: " << k << " " << endl;
\r
243 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;
\r
244 cout << "Difference with noise of point: " << diff << endl;
\r
245 cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl;
\r
248 void CV_HomographyTest::run(int)
\r
250 for (size_t N = 4; N <= MAX_COUNT_OF_POINTS; ++N)
\r
252 RNG& rng = ts->get_rng();
\r
254 float *src_data = new float [2*N];
\r
256 for (size_t i = 0; i < N; ++i)
\r
258 src_data[2*i] = (float)cvtest::randReal(rng)*image_size;
\r
259 src_data[2*i+1] = (float)cvtest::randReal(rng)*image_size;
\r
262 cv::Mat src_mat_2f(1, N, CV_32FC2, src_data),
\r
263 src_mat_2d(2, N, CV_32F, src_data),
\r
264 src_mat_3d(3, N, CV_32F);
\r
265 cv::Mat dst_mat_2f, dst_mat_2d, dst_mat_3d;
\r
267 vector <Point2f> src_vec, dst_vec;
\r
269 for (size_t i = 0; i < N; ++i)
\r
271 float *tmp = src_mat_2d.ptr<float>()+2*i;
\r
272 src_mat_3d.at<float>(0, i) = tmp[0];
\r
273 src_mat_3d.at<float>(1, i) = tmp[1];
\r
274 src_mat_3d.at<float>(2, i) = 1.0f;
\r
276 src_vec.push_back(Point2f(tmp[0], tmp[1]));
\r
279 double fi = cvtest::randReal(rng)*2*CV_PI;
\r
281 double t_x = cvtest::randReal(rng)*sqrt(image_size*1.0),
\r
282 t_y = cvtest::randReal(rng)*sqrt(image_size*1.0);
\r
284 double Hdata[9] = { cos(fi), -sin(fi), t_x,
\r
285 sin(fi), cos(fi), t_y,
\r
286 0.0f, 0.0f, 1.0f };
\r
288 cv::Mat H_64(3, 3, CV_64F, Hdata), H_32;
\r
290 H_64.convertTo(H_32, CV_32F);
\r
292 dst_mat_3d = H_32*src_mat_3d;
\r
294 dst_mat_2d.create(2, N, CV_32F); dst_mat_2f.create(1, N, CV_32FC2);
\r
296 for (size_t i = 0; i < N; ++i)
\r
298 float *tmp_2f = dst_mat_2f.ptr<float>()+2*i;
\r
299 tmp_2f[0] = dst_mat_2d.at<float>(0, i) = dst_mat_3d.at<float>(0, i) /= dst_mat_3d.at<float>(2, i);
\r
300 tmp_2f[1] = dst_mat_2d.at<float>(1, i) = dst_mat_3d.at<float>(1, i) /= dst_mat_3d.at<float>(2, i);
\r
301 dst_mat_3d.at<float>(2, i) = 1.0f;
\r
303 dst_vec.push_back(Point2f(tmp_2f[0], tmp_2f[1]));
\r
306 for (size_t i = 0; i < METHODS_COUNT; ++i)
\r
308 method = METHOD[i];
\r
314 Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method),
\r
315 cv::findHomography(src_mat_2f, dst_vec, method),
\r
316 cv::findHomography(src_vec, dst_mat_2f, method),
\r
317 cv::findHomography(src_vec, dst_vec, method) };
\r
319 for (size_t j = 0; j < 4; ++j)
\r
322 if (!check_matrix_size(H_res_64[j]))
\r
324 print_information_1(j, N, method, H_res_64[j]);
\r
325 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
\r
331 for (size_t k = 0; k < COUNT_NORM_TYPES; ++k)
\r
332 if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff))
\r
334 print_information_2(j, N, method, H_64, H_res_64[j], k, diff);
\r
335 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF);
\r
344 cv::Mat mask [4]; double diff;
\r
346 Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask[0]),
\r
347 cv::findHomography(src_mat_2f, dst_vec, CV_RANSAC, reproj_threshold, mask[1]),
\r
348 cv::findHomography(src_vec, dst_mat_2f, CV_RANSAC, reproj_threshold, mask[2]),
\r
349 cv::findHomography(src_vec, dst_vec, CV_RANSAC, reproj_threshold, mask[3]) };
\r
351 for (size_t j = 0; j < 4; ++j)
\r
354 if (!check_matrix_size(H_res_64[j]))
\r
356 print_information_1(j, N, method, H_res_64[j]);
\r
357 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
\r
361 for (size_t k = 0; k < COUNT_NORM_TYPES; ++k)
\r
362 if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff))
\r
364 print_information_2(j, N, method, H_64, H_res_64[j], k, diff);
\r
365 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF);
\r
369 int code = check_ransac_mask_1(src_mat_2f, mask[j]);
\r
373 print_information_3(j, N, mask[j]);
\r
377 case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; }
\r
378 case 2: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_2); break; }
\r
379 case 3: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3); break; }
\r
396 Mat noise_2f(1, N, CV_32FC2);
\r
397 rng.fill(noise_2f, RNG::NORMAL, Scalar::all(0), Scalar::all(sigma));
\r
399 cv::Mat mask(N, 1, CV_8UC1);
\r
401 for (size_t i = 0; i < N; ++i)
\r
403 float *a = noise_2f.ptr<float>()+2*i, *_2f = dst_mat_2f.ptr<float>()+2*i;
\r
404 _2f[0] += a[0]; _2f[1] += a[1];
\r
405 mask.at<bool>(i, 0) = !(sqrt(a[0]*a[0]+a[1]*a[1]) > reproj_threshold);
\r
408 for (size_t i = 0; i < METHODS_COUNT; ++i)
\r
410 method = METHOD[i];
\r
416 Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f),
\r
417 cv::findHomography(src_mat_2f, dst_vec),
\r
418 cv::findHomography(src_vec, dst_mat_2f),
\r
419 cv::findHomography(src_vec, dst_vec) };
\r
421 for (size_t j = 0; j < 4; ++j)
\r
424 if (!check_matrix_size(H_res_64[j]))
\r
426 print_information_1(j, N, method, H_res_64[j]);
\r
427 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
\r
431 Mat H_res_32; H_res_64[j].convertTo(H_res_32, CV_32F);
\r
433 cv::Mat dst_res_3d(3, N, CV_32F), noise_2d(2, N, CV_32F);
\r
435 for (size_t k = 0; k < N; ++k)
\r
438 Mat tmp_mat_3d = H_res_32*src_mat_3d.col(k);
\r
440 dst_res_3d.at<float>(0, k) = tmp_mat_3d.at<float>(0, 0) /= tmp_mat_3d.at<float>(2, 0);
\r
441 dst_res_3d.at<float>(1, k) = tmp_mat_3d.at<float>(1, 0) /= tmp_mat_3d.at<float>(2, 0);
\r
442 dst_res_3d.at<float>(2, k) = tmp_mat_3d.at<float>(2, 0) = 1.0f;
\r
444 float *a = noise_2f.ptr<float>()+2*k;
\r
445 noise_2d.at<float>(0, k) = a[0]; noise_2d.at<float>(1, k) = a[1];
\r
447 for (size_t l = 0; l < COUNT_NORM_TYPES; ++l)
\r
448 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)
\r
450 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]));
\r
451 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_1);
\r
457 for (size_t l = 0; l < COUNT_NORM_TYPES; ++l)
\r
458 if (cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[l]) - cv::norm(noise_2d, NORM_TYPE[l]) > max_diff)
\r
460 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]));
\r
461 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_2);
\r
471 cv::Mat mask_res [4];
\r
473 Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res[0]),
\r
474 cv::findHomography(src_mat_2f, dst_vec, CV_RANSAC, reproj_threshold, mask_res[1]),
\r
475 cv::findHomography(src_vec, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res[2]),
\r
476 cv::findHomography(src_vec, dst_vec, CV_RANSAC, reproj_threshold, mask_res[3]) };
\r
478 for (size_t j = 0; j < 4; ++j)
\r
481 if (!check_matrix_size(H_res_64[j]))
\r
483 print_information_1(j, N, method, H_res_64[j]);
\r
484 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
\r
488 int code = check_ransac_mask_2(mask, mask_res[j]);
\r
492 print_information_3(j, N, mask_res[j]);
\r
496 case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; }
\r
497 case 2: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3); break; }
\r
505 cv::Mat H_res_32; H_res_64[j].convertTo(H_res_32, CV_32F);
\r
507 cv::Mat dst_res_3d = H_res_32*src_mat_3d;
\r
509 for (size_t k = 0; k < N; ++k)
\r
511 dst_res_3d.at<float>(0, k) /= dst_res_3d.at<float>(2, k);
\r
512 dst_res_3d.at<float>(1, k) /= dst_res_3d.at<float>(2, k);
\r
513 dst_res_3d.at<float>(2, k) = 1.0f;
\r
515 float *p = dst_mat_2f.ptr<float>()+2*k;
\r
517 dst_mat_3d.at<float>(0, k) = p[0];
\r
518 dst_mat_3d.at<float>(1, k) = p[1];
\r
520 double diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_L2);
\r
522 if (mask_res[j].at<bool>(k, 0) != (diff <= reproj_threshold))
\r
524 print_information_6(j, N, k, diff, mask_res[j].at<bool>(k, 0));
\r
525 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_4);
\r
529 if (mask.at<bool>(k, 0) && !mask_res[j].at<bool>(k, 0))
\r
531 print_information_7(j, N, k, diff, mask.at<bool>(k, 0), mask_res[j].at<bool>(k, 0));
\r
532 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_5);
\r
536 if (mask_res[j].at<bool>(k, 0))
\r
538 float *a = noise_2f.ptr<float>()+2*k;
\r
539 dst_mat_3d.at<float>(0, k) -= a[0];
\r
540 dst_mat_3d.at<float>(1, k) -= a[1];
\r
542 cv::Mat noise_2d(2, 1, CV_32F);
\r
543 noise_2d.at<float>(0, 0) = a[0]; noise_2d.at<float>(1, 0) = a[1];
\r
545 for (size_t l = 0; l < COUNT_NORM_TYPES; ++l)
\r
547 diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_TYPE[l]);
\r
549 if (diff - cv::norm(noise_2d, NORM_TYPE[l]) > max_2diff)
\r
551 print_information_8(j, N, k, l, diff - cv::norm(noise_2d, NORM_TYPE[l]));
\r
552 CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF, MESSAGE_RANSAC_DIFF);
\r
569 TEST(Calib3d_Homography, accuracy) { CV_HomographyTest test; test.safe_run(); }
\r