From fb22028be33de58477d1ee62b445f646eef57a0b Mon Sep 17 00:00:00 2001 From: razerhell Date: Wed, 17 Jan 2018 17:05:13 +0800 Subject: [PATCH] Merge pull request #10574 from razerhell:patch-1 * Newton's method can be more efficient when we get the result of function distortPoint with a point (0, 0) and then undistortPoint with the result, we get the point not (0, 0). and then we discovered that the old method is not convergence sometimes. finally we have gotten the right values by Newton's method. * modify by advice Newton's method...#10574 * calib3d(fisheye): fix codestyle, update theta before exit EPS check --- modules/calib3d/src/fisheye.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/calib3d/src/fisheye.cpp b/modules/calib3d/src/fisheye.cpp index 3ed9ba43f1..96d74cc141 100644 --- a/modules/calib3d/src/fisheye.cpp +++ b/modules/calib3d/src/fisheye.cpp @@ -388,10 +388,18 @@ void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted { // compensate distortion iteratively double theta = theta_d; - for(int j = 0; j < 10; j++ ) + + const double EPS = 1e-8; // or std::numeric_limits::epsilon(); + for (int j = 0; j < 10; j++) { double theta2 = theta*theta, theta4 = theta2*theta2, theta6 = theta4*theta2, theta8 = theta6*theta2; - theta = theta_d / (1 + k[0] * theta2 + k[1] * theta4 + k[2] * theta6 + k[3] * theta8); + double k0_theta2 = k[0] * theta2, k1_theta4 = k[1] * theta4, k2_theta6 = k[2] * theta6, k3_theta8 = k[3] * theta8; + /* new_theta = theta - theta_fix, theta_fix = f0(theta) / f0'(theta) */ + double theta_fix = (theta * (1 + k0_theta2 + k1_theta4 + k2_theta6 + k3_theta8) - theta_d) / + (1 + 3*k0_theta2 + 5*k1_theta4 + 7*k2_theta6 + 9*k3_theta8); + theta = theta - theta_fix; + if (fabs(theta_fix) < EPS) + break; } scale = std::tan(theta) / theta_d;