Commit 70820224 authored by Alexander Reshetnikov's avatar Alexander Reshetnikov

added checking homography matrix computing for vector <Point2f>

parent b5034ac3
...@@ -13,11 +13,12 @@ ...@@ -13,11 +13,12 @@
#define MESSAGE_REPROJ_DIFF_2 "Reprojection error is not optimal." #define MESSAGE_REPROJ_DIFF_2 "Reprojection error is not optimal."
#define MESSAGE_RANSAC_MASK_1 "Sizes of inliers/outliers mask are incorrect." #define MESSAGE_RANSAC_MASK_1 "Sizes of inliers/outliers mask are incorrect."
#define MESSAGE_RANSAC_MASK_2 "Mask mustn't have any outliers." #define MESSAGE_RANSAC_MASK_2 "Mask mustn't have any outliers."
#define MESSAGE_RANSAC_MASK_3 "Mask of inliers/outliers is incorrect." #define MESSAGE_RANSAC_MASK_3 "All values of mask must be 1 (true) or 0 (false)."
#define MESSAGE_RANSAC_MASK_4 "Inlier in original mask shouldn't be outlier in found mask." #define MESSAGE_RANSAC_MASK_4 "Mask of inliers/outliers is incorrect."
#define MESSAGE_RANSAC_MASK_5 "Inlier in original mask shouldn't be outlier in found mask."
#define MESSAGE_RANSAC_DIFF "Reprojection error for current pair of points more than required." #define MESSAGE_RANSAC_DIFF "Reprojection error for current pair of points more than required."
#define MAX_COUNT_OF_POINTS 500 #define MAX_COUNT_OF_POINTS 303
#define COUNT_NORM_TYPES 3 #define COUNT_NORM_TYPES 3
#define METHODS_COUNT 3 #define METHODS_COUNT 3
...@@ -63,8 +64,17 @@ class CV_HomographyTest: public cvtest::ArrayTest ...@@ -63,8 +64,17 @@ class CV_HomographyTest: public cvtest::ArrayTest
bool check_matrix_size(const cv::Mat& H); 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_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); // bool check_reproj_error(const cv::Mat& src_3d, const cv::Mat& dst_3d, const int norm_type = NORM_L2);
bool check_ransac_mask_1(const Mat& src, const Mat& mask); int check_ransac_mask_1(const Mat& src, const Mat& mask);
bool check_ransac_mask_2(const Mat& original_mask, const Mat& found_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);
void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);
void print_information_3(int j, int N, const Mat& mask);
void print_information_4(int method, int j, int N, int k, int l, double diff);
void print_information_5(int method, int j, int N, int l, double diff);
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(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 <cv::Point2f> dst_points, const cv::Mat& H, const int norm_type = NORM_L2); void check_transform_quality(const cv::InputArray src_points, const vector <cv::Point2f> dst_points, const cv::Mat& H, const int norm_type = NORM_L2);
...@@ -72,8 +82,6 @@ class CV_HomographyTest: public cvtest::ArrayTest ...@@ -72,8 +82,6 @@ class CV_HomographyTest: public cvtest::ArrayTest
void check_transform_quality(const vector <cv::Point2f> src_points, const vector <cv::Point2f> dst_points, const cv::Mat& H, const int norm_type = NORM_L2); void check_transform_quality(const vector <cv::Point2f> src_points, const vector <cv::Point2f> dst_points, const cv::Mat& H, const int norm_type = NORM_L2);
}; };
/* void CV_HomographyTest::run_func () {} */
CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2), max_2diff(2e-2) CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2), max_2diff(2e-2)
{ {
test_array[INPUT].push_back(NULL); test_array[INPUT].push_back(NULL);
...@@ -536,28 +544,126 @@ bool CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat ...@@ -536,28 +544,126 @@ bool CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat
return diff <= max_diff; return diff <= max_diff;
} }
bool CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask) int CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask)
{ {
if (!(mask.cols == 1) && (mask.rows == src.cols)) if (!(mask.cols == 1) && (mask.rows == src.cols)) return 1;
{ if (countNonZero(mask) < mask.rows) return 2;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); for (size_t i = 0; i < mask.rows; ++i) if (mask.at<uchar>(i, 0) > 1) return 3;
return false; return 0;
}
if (countNonZero(mask) < mask.rows)
{
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_2);
return false;
}
return true;
} }
bool CV_HomographyTest::check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask) 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)) 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<uchar>(i, 0) > 1) return 2;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); return 0;
return false; }
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
}
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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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 <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; 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;
} }
void CV_HomographyTest::check_transform_quality(cv::InputArray src_points, cv::InputArray dst_points, const cv::Mat& H, const int norm_type) void CV_HomographyTest::check_transform_quality(cv::InputArray src_points, cv::InputArray dst_points, const cv::Mat& H, const int norm_type)
...@@ -594,12 +700,16 @@ void CV_HomographyTest::run(int) ...@@ -594,12 +700,16 @@ void CV_HomographyTest::run(int)
src_mat_3d(3, N, CV_32F); src_mat_3d(3, N, CV_32F);
cv::Mat dst_mat_2f, dst_mat_2d, dst_mat_3d; cv::Mat dst_mat_2f, dst_mat_2d, dst_mat_3d;
vector <Point2f> src_vec, dst_vec;
for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
{ {
float *tmp = src_mat_2d.ptr<float>()+2*i; float *tmp = src_mat_2d.ptr<float>()+2*i;
src_mat_3d.at<float>(0, i) = tmp[0]; src_mat_3d.at<float>(0, i) = tmp[0];
src_mat_3d.at<float>(1, i) = tmp[1]; src_mat_3d.at<float>(1, i) = tmp[1];
src_mat_3d.at<float>(2, i) = 1.0f; src_mat_3d.at<float>(2, i) = 1.0f;
src_vec.push_back(Point2f(tmp[0], tmp[1]));
} }
double fi = cvtest::randReal(rng)*2*CV_PI; double fi = cvtest::randReal(rng)*2*CV_PI;
...@@ -624,6 +734,9 @@ void CV_HomographyTest::run(int) ...@@ -624,6 +734,9 @@ void CV_HomographyTest::run(int)
float *tmp_2f = dst_mat_2f.ptr<float>()+2*i; float *tmp_2f = dst_mat_2f.ptr<float>()+2*i;
tmp_2f[0] = dst_mat_2d.at<float>(0, i) = dst_mat_3d.at<float>(0, i) /= dst_mat_3d.at<float>(2, i); tmp_2f[0] = dst_mat_2d.at<float>(0, i) = dst_mat_3d.at<float>(0, i) /= dst_mat_3d.at<float>(2, i);
tmp_2f[1] = dst_mat_2d.at<float>(1, i) = dst_mat_3d.at<float>(1, i) /= dst_mat_3d.at<float>(2, i); tmp_2f[1] = dst_mat_2d.at<float>(1, i) = dst_mat_3d.at<float>(1, i) /= dst_mat_3d.at<float>(2, i);
dst_mat_3d.at<float>(2, i) = 1.0f;
dst_vec.push_back(Point2f(tmp_2f[0], tmp_2f[1]));
} }
for (size_t i = 0; i < METHODS_COUNT; ++i) for (size_t i = 0; i < METHODS_COUNT; ++i)
...@@ -634,67 +747,81 @@ void CV_HomographyTest::run(int) ...@@ -634,67 +747,81 @@ void CV_HomographyTest::run(int)
case 0: case 0:
case CV_LMEDS: case CV_LMEDS:
{ {
Mat H_res_64 = cv::findHomography(src_mat_2f, dst_mat_2f, method); Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method),
if (!check_matrix_size(H_res_64)) 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)
{ {
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
cout << "Count of points: " << N << endl; cout << endl; if (!check_matrix_size(H_res_64[j]))
cout << "Homography matrix:" << endl; cout << endl; {
cout << H_res_64 << endl; cout << endl; print_information_1(j, N, method, H_res_64[j]);
cout << "Number of rows: " << H_res_64.rows << " Number of cols: " << H_res_64.cols << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
return; return;
} }
double diff; double diff;
for (size_t j = 0; j < COUNT_NORM_TYPES; ++j) for (size_t k = 0; k < COUNT_NORM_TYPES; ++k)
if (!check_matrix_diff(H_64, H_res_64, NORM_TYPE[j], diff)) if (!check_matrix_diff(H_64, H_res_64[j], NORM_TYPE[k], diff))
{ {
cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl; print_information_2(j, N, method, H_64, H_res_64[j], k, diff);
cout << "Count of points: " << N << endl; cout << endl;
cout << "Original matrix:" << endl; cout << endl;
cout << H_64 << endl; cout << endl;
cout << "Found matrix:" << endl; cout << endl;
cout << H_res_64 << endl; cout << endl;
cout << "Norm type using in criteria: "; if (NORM_TYPE[j] == 1) cout << "INF"; else if (NORM_TYPE[j] == 2) cout << "L1"; else cout << "L2"; cout << endl;
cout << "Difference between matrix: " << diff << endl;
cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF);
return; return;
} }
}
continue; continue;
} }
case CV_RANSAC: case CV_RANSAC:
{ {
cv::Mat mask; double diff; cv::Mat mask [4]; double diff;
Mat H_res_64 = cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask);
if (!check_matrix_size(H_res_64)) 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)
{ {
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
cout << "Count of points: " << N << endl; cout << endl; if (!check_matrix_size(H_res_64[j]))
cout << "Homography matrix:" << endl; cout << endl; {
cout << H_res_64 << endl; cout << endl; print_information_1(j, N, method, H_res_64[j]);
cout << "Number of rows: " << H_res_64.rows << " Number of cols: " << H_res_64.cols << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
return; return;
} }
for (size_t j = 0; j < COUNT_NORM_TYPES; ++j)
if (!check_matrix_diff(H_64, H_res_64, NORM_TYPE[j], 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))
{ {
cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl; print_information_2(j, N, method, H_64, H_res_64[j], k, diff);
cout << "Count of points: " << N << endl; cout << endl;
cout << "Original matrix:" << endl; cout << endl;
cout << H_64 << endl; cout << endl;
cout << "Found matrix:" << endl; cout << endl;
cout << H_res_64 << endl; cout << endl;
cout << "Norm type using in criteria: "; if (NORM_TYPE[j] == 1) cout << "INF"; else if (NORM_TYPE[j] == 2) cout << "L1"; else cout << "L2"; cout << endl;
cout << "Difference between matrix: " << diff << endl;
cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_DIFF, MESSAGE_MATRIX_DIFF);
return; return;
} }
if (!check_ransac_mask_1(src_mat_2f, mask)) 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; continue;
} }
...@@ -712,7 +839,7 @@ void CV_HomographyTest::run(int) ...@@ -712,7 +839,7 @@ void CV_HomographyTest::run(int)
float *a = noise_2f.ptr<float>()+2*i, *_2f = dst_mat_2f.ptr<float>()+2*i; float *a = noise_2f.ptr<float>()+2*i, *_2f = dst_mat_2f.ptr<float>()+2*i;
_2f[0] /* = dst_mat_2d.at<float>(0, i) = dst_mat_3d.at<float>(0, i) */ += a[0]; _2f[0] /* = dst_mat_2d.at<float>(0, i) = dst_mat_3d.at<float>(0, i) */ += a[0];
_2f[1] /* = dst_mat_2d.at<float>(1, i) = dst_mat_3d.at<float>(1, i) */ += a[1]; _2f[1] /* = dst_mat_2d.at<float>(1, i) = dst_mat_3d.at<float>(1, i) */ += a[1];
mask.at<uchar>(i, 0) = sqrt(a[0]*a[0]+a[1]*a[1]) > reproj_threshold ? 0 : 1; mask.at<bool>(i, 0) = !(sqrt(a[0]*a[0]+a[1]*a[1]) > reproj_threshold);
} }
for (size_t i = 0; i < METHODS_COUNT; ++i) for (size_t i = 0; i < METHODS_COUNT; ++i)
...@@ -723,20 +850,22 @@ void CV_HomographyTest::run(int) ...@@ -723,20 +850,22 @@ void CV_HomographyTest::run(int)
case 0: case 0:
case CV_LMEDS: case CV_LMEDS:
{ {
Mat H_res_64 = cv::findHomography(src_mat_2f, dst_mat_2f, mask); 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) };
if (!check_matrix_size(H_res_64)) for (size_t j = 0; j < 4; ++j)
{ {
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
cout << "Count of points: " << N << endl; cout << endl; if (!check_matrix_size(H_res_64[j]))
cout << "Homography matrix:" << endl; cout << endl; {
cout << H_res_64 << endl; cout << endl; print_information_1(j, N, method, H_res_64[j]);
cout << "Number of rows: " << H_res_64.rows << " Number of cols: " << H_res_64.cols << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
return; return;
} }
Mat H_res_32; H_res_64.convertTo(H_res_32, CV_32F); 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); cv::Mat dst_res_3d(3, N, CV_32F), noise_2d(2, N, CV_32F);
...@@ -752,17 +881,10 @@ void CV_HomographyTest::run(int) ...@@ -752,17 +881,10 @@ void CV_HomographyTest::run(int)
float *a = noise_2f.ptr<float>()+2*k; float *a = noise_2f.ptr<float>()+2*k;
noise_2d.at<float>(0, k) = a[0]; noise_2d.at<float>(1, k) = a[1]; noise_2d.at<float>(0, k) = a[0]; noise_2d.at<float>(1, k) = a[1];
for (size_t j = 0; j < METHODS_COUNT; ++j) for (size_t l = 0; l < COUNT_NORM_TYPES; ++l)
if (cv::norm(tmp_mat_3d, dst_mat_3d.col(k), NORM_TYPE[j]) - cv::norm(noise_2d.col(k), NORM_TYPE[j]) > max_2diff) 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)
{ {
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; 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]));
cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << 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[j] == 1) cout << "INF"; else if (NORM_TYPE[j] == 2) cout << "L1"; else cout << "L2"; cout << endl;
cout << "Difference with noise of point: " << cv::norm(tmp_mat_3d, dst_mat_3d.col(k), NORM_TYPE[j]) - cv::norm(noise_2d.col(k), NORM_TYPE[j]) << endl;
cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_1); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_1);
return; return;
} }
...@@ -771,41 +893,55 @@ void CV_HomographyTest::run(int) ...@@ -771,41 +893,55 @@ void CV_HomographyTest::run(int)
Mat tmp_mat_3d = H_res_32*src_mat_3d; Mat tmp_mat_3d = H_res_32*src_mat_3d;
for (size_t j = 0; j < METHODS_COUNT; ++j) for (size_t l = 0; l < COUNT_NORM_TYPES; ++l)
if (cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[j]) - cv::norm(noise_2d, NORM_TYPE[j]) > max_diff) if (cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[l]) - cv::norm(noise_2d, NORM_TYPE[l]) > max_diff)
{ {
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; 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]));
cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
cout << "Sigma of normal noise: " << sigma << endl;
cout << "Count of points: " << N << endl;
cout << "Norm type using in criteria: "; if (NORM_TYPE[j] == 1) cout << "INF"; else if (NORM_TYPE[j] == 2) cout << "L1"; else cout << "L2"; cout << endl;
cout << "Difference with noise of points: " << cv::norm(dst_res_3d, dst_mat_3d, NORM_TYPE[j]) - cv::norm(noise_2d, NORM_TYPE[j]) << endl;
cout << "Maxumum allowed difference: " << max_diff << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_2); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_REPROJ_DIFF, MESSAGE_REPROJ_DIFF_2);
return; return;
} }
}
continue; continue;
} }
case CV_RANSAC: case CV_RANSAC:
{ {
cv::Mat mask_res; cv::Mat mask_res [4];
Mat H_res_64 = cv::findHomography(src_mat_2f, dst_mat_2f, CV_RANSAC, reproj_threshold, mask_res);
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]) };
if (!check_matrix_size(H_res_64)) for (size_t j = 0; j < 4; ++j)
{ {
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
cout << "Count of points: " << N << endl; cout << endl; if (!check_matrix_size(H_res_64[j]))
cout << "Homography matrix:" << endl; cout << endl; {
cout << H_res_64 << endl; cout << endl; print_information_1(j, N, method, H_res_64[j]);
cout << "Number of rows: " << H_res_64.rows << " Number of cols: " << H_res_64.cols << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_MATRIX_SIZE, MESSAGE_MATRIX_SIZE);
return; return;
} }
if (!check_ransac_mask_2(mask, mask_res)) return; int code = check_ransac_mask_2(mask, mask_res[j]);
cv::Mat H_res_32; H_res_64.convertTo(H_res_32, CV_32F); 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; cv::Mat dst_res_3d = H_res_32*src_mat_3d;
...@@ -822,33 +958,21 @@ void CV_HomographyTest::run(int) ...@@ -822,33 +958,21 @@ void CV_HomographyTest::run(int)
double diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_L2); double diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_L2);
if (mask_res.at<bool>(k, 0) != (diff <= reproj_threshold)) if (mask_res[j].at<bool>(k, 0) != (diff <= reproj_threshold))
{ {
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; print_information_6(j, N, k, diff, mask_res[j].at<bool>(k, 0));
cout << "Count of points: " << N << " " << endl; CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_4);
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: "<< mask_res.at<bool>(k, 0) << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_3);
return; return;
} }
if (mask.at<bool>(k, 0) && !mask_res[j].at<bool>(k, 0))
if (mask.at<bool>(k, 0) && !mask_res.at<bool>(k, 0))
{ {
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl; print_information_7(j, N, k, diff, mask.at<bool>(k, 0), mask_res[j].at<bool>(k, 0));
cout << "Count of points: " << N << " " << endl; CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_5);
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: "<< mask.at<bool>(k, 0) << " Value of found mask: " << mask_res.at<bool>(k, 0) << endl; cout << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_4);
return; return;
} }
if (mask_res.at<bool>(k, 0)) if (mask_res[j].at<bool>(k, 0))
{ {
float *a = noise_2f.ptr<float>()+2*k; float *a = noise_2f.ptr<float>()+2*k;
dst_mat_3d.at<float>(0, k) -= a[0]; dst_mat_3d.at<float>(0, k) -= a[0];
...@@ -857,26 +981,20 @@ void CV_HomographyTest::run(int) ...@@ -857,26 +981,20 @@ void CV_HomographyTest::run(int)
cv::Mat noise_2d(2, 1, CV_32F); cv::Mat noise_2d(2, 1, CV_32F);
noise_2d.at<float>(0, 0) = a[0]; noise_2d.at<float>(1, 0) = a[1]; noise_2d.at<float>(0, 0) = a[0]; noise_2d.at<float>(1, 0) = a[1];
for (size_t j = 0; j < METHODS_COUNT; ++j) 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[j]); diff = cv::norm(dst_res_3d.col(k), dst_mat_3d.col(k), NORM_TYPE[l]);
if (diff - cv::norm(noise_2d, NORM_TYPE[j]) > max_2diff) 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]));
cout << endl; cout << "Checking for reprojection error of inlier..." << endl; cout << endl;
cout << "Count of points: " << N << " " << endl;
cout << "Number of point: " << k << " " << endl;
cout << "Reprojection error for this point: " << diff << " " << endl;
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF, MESSAGE_RANSAC_DIFF); CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF, MESSAGE_RANSAC_DIFF);
return; return;
} }
} }
} }
} }
}
// Checking of reprojection error for any points pair.
continue; continue;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment