From ace71cef3f635517a17e9e8f2091e8e3d3ff267a Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Thu, 21 Nov 2013 21:20:20 +0400 Subject: [PATCH] Added Affine3::rvec() --- modules/core/include/opencv2/core/affine.hpp | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/modules/core/include/opencv2/core/affine.hpp b/modules/core/include/opencv2/core/affine.hpp index cadc7ee26f..fa7eed8638 100644 --- a/modules/core/include/opencv2/core/affine.hpp +++ b/modules/core/include/opencv2/core/affine.hpp @@ -97,6 +97,9 @@ namespace cv Mat3 linear() const; Vec3 translation() const; + //Rodrigues vector + Vec3 rvec() const; + Affine3 inv(int method = cv::DECOMP_SVD) const; // a.rotate(R) is equivalent to Affine(R, 0) * a; @@ -300,6 +303,55 @@ typename cv::Affine3::Vec3 cv::Affine3::translation() const return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]); } +template inline +typename cv::Affine3::Vec3 cv::Affine3::rvec() const +{ + cv::Vec3d w; + cv::Matx33d u, vt, R = rotation(); + cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A); + R = u * vt; + + double rx = R.val[7] - R.val[5]; + double ry = R.val[2] - R.val[6]; + double rz = R.val[3] - R.val[1]; + + double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25); + double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5; + c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c; + double theta = acos(c); + + if( s < 1e-5 ) + { + if( c > 0 ) + rx = ry = rz = 0; + else + { + double t; + t = (R.val[0] + 1) * 0.5; + rx = std::sqrt(std::max(t, 0.0)); + t = (R.val[4] + 1) * 0.5; + ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0); + t = (R.val[8] + 1) * 0.5; + rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0); + + if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) ) + rz = -rz; + theta /= std::sqrt(rx*rx + ry*ry + rz*rz); + rx *= theta; + ry *= theta; + rz *= theta; + } + } + else + { + double vth = 1/(2*s); + vth *= theta; + rx *= vth; ry *= vth; rz *= vth; + } + + return cv::Vec3d(rx, ry, rz); +} + template inline cv::Affine3 cv::Affine3::inv(int method) const { -- GitLab