12 #include <mrpt/3rdparty/do_opencv_includes.h> 34 dls(
const cv::Mat& opoints,
const cv::Mat& ipoints);
46 template <
typename Opo
intType,
typename Ipo
intType>
47 void init_points(
const cv::Mat& opoints,
const cv::Mat& ipoints)
49 for (
int i = 0; i <
N; i++)
51 p.at<
double>(0, i) = opoints.at<OpointType>(i, 0);
52 p.at<
double>(1, i) = opoints.at<OpointType>(i, 1);
53 p.at<
double>(2, i) = opoints.at<OpointType>(i, 2);
56 mn.at<
double>(0) +=
p.at<
double>(0, i);
57 mn.at<
double>(1) +=
p.at<
double>(1, i);
58 mn.at<
double>(2) +=
p.at<
double>(2, i);
61 double sr = std::pow(ipoints.at<IpointType>(i, 0), 2) +
62 std::pow(ipoints.at<IpointType>(i, 1), 2) + (double)1;
65 z.at<
double>(0, i) = ipoints.at<IpointType>(i, 0) / sr;
66 z.at<
double>(1, i) = ipoints.at<IpointType>(i, 1) / sr;
67 z.at<
double>(2, i) = (
double)1 / sr;
70 mn.at<
double>(0) /= (
double)
N;
71 mn.at<
double>(1) /= (
double)
N;
72 mn.at<
double>(2) /= (
double)
N;
106 const cv::Mat& Mtilde, cv::Mat& eigenval_real, cv::Mat& eigenval_imag,
107 cv::Mat& eigenvec_real, cv::Mat& eigenvec_imag);
124 const std::vector<double>& a,
const std::vector<double>& b,
125 const std::vector<double>& c,
const std::vector<double>& u);
133 cv::Mat
Hessian(
const double s[]);
147 cv::Mat
skewsymm(
const cv::Mat* X1);
154 cv::Mat
rotx(
const double t);
161 cv::Mat
roty(
const double t);
168 cv::Mat
rotz(
const double t);
175 cv::Mat
mean(
const cv::Mat& M);
203 class EigenvalueDecomposition
213 cv::Mat _eigenvalues;
215 cv::Mat _eigenvectors;
222 template <
typename _Tp>
234 template <
typename _Tp>
235 _Tp* alloc_1d(
int m, _Tp
val)
237 _Tp* arr = alloc_1d<_Tp>(m);
238 for (
int i = 0; i < m; i++) arr[i] =
val;
248 template <
typename _Tp>
249 _Tp** alloc_2d(
int m,
int _n)
251 _Tp** arr =
new _Tp*[m];
252 for (
int i = 0; i < m; i++) arr[i] =
new _Tp[_n];
263 template <
typename _Tp>
264 _Tp** alloc_2d(
int m,
int _n, _Tp
val)
266 _Tp** arr = alloc_2d<_Tp>(m, _n);
267 for (
int i = 0; i < m; i++)
269 for (
int j = 0; j < _n; j++)
284 void cdiv(
double xr,
double xi,
double yr,
double yi)
287 if (std::abs(yr) > std::abs(yi))
291 cdivr = (xr + r * xi) / dv;
292 cdivi = (xi - r * xr) / dv;
298 cdivr = (r * xr + xi) / dv;
299 cdivi = (r * xi - xr) / dv;
318 double eps = std::pow(2.0, -52.0);
319 double exshift = 0.0;
320 double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
325 for (
int i = 0; i < nn; i++)
327 if (i < low || i > high)
332 for (
int j = std::max(i - 1, 0); j < nn; j++)
346 s = std::abs(H[l - 1][l - 1]) + std::abs(H[l][l]);
351 if (std::abs(H[l][l - 1]) <
eps * s)
363 H[n1][n1] = H[n1][n1] + exshift;
371 else if (l == n1 - 1)
373 w = H[n1][n1 - 1] * H[n1 - 1][n1];
374 p = (H[n1 - 1][n1 - 1] - H[n1][n1]) / 2.0;
376 z = std::sqrt(std::abs(q));
377 H[n1][n1] = H[n1][n1] + exshift;
378 H[n1 - 1][n1 - 1] = H[n1 - 1][n1 - 1] + exshift;
402 s = std::abs(x) + std::abs(z);
405 r = std::sqrt(p * p + q * q);
411 for (
int j = n1 - 1; j < nn; j++)
414 H[n1 - 1][j] = q * z + p * H[n1][j];
415 H[n1][j] = q * H[n1][j] - p * z;
420 for (
int i = 0; i <= n1; i++)
423 H[i][n1 - 1] = q * z + p * H[i][n1];
424 H[i][n1] = q * H[i][n1] - p * z;
429 for (
int i = low; i <= high; i++)
432 V[i][n1 - 1] = q * z + p * V[i][n1];
433 V[i][n1] = q * V[i][n1] - p * z;
459 y = H[n1 - 1][n1 - 1];
460 w = H[n1][n1 - 1] * H[n1 - 1][n1];
468 for (
int i = low; i <= n1; i++)
472 s = std::abs(H[n1][n1 - 1]) + std::abs(H[n1 - 1][n1 - 2]);
490 s = x - w / ((y - x) / 2.0 + s);
491 for (
int i = low; i <= n1; i++)
509 p = (r * s - w) / H[m + 1][m] + H[m][m + 1];
510 q = H[m + 1][m + 1] - z - r - s;
512 s = std::abs(p) + std::abs(q) + std::abs(r);
520 if (std::abs(H[m][m - 1]) * (std::abs(q) + std::abs(r)) <
522 (std::abs(H[m - 1][m - 1]) + std::abs(z) +
523 std::abs(H[m + 1][m + 1]))))
530 for (
int i = m + 2; i <= n1; i++)
541 for (
int k = m; k <= n1 - 1; k++)
543 bool notlast = (k != n1 - 1);
548 r = (notlast ? H[k + 2][k - 1] : 0.0);
549 x = std::abs(p) + std::abs(q) + std::abs(r);
561 s = std::sqrt(p * p + q * q + r * r);
570 H[k][k - 1] = -s * x;
574 H[k][k - 1] = -H[k][k - 1];
585 for (
int j = k; j < nn; j++)
587 p = H[k][j] + q * H[k + 1][j];
590 p = p + r * H[k + 2][j];
591 H[k + 2][j] = H[k + 2][j] - p * z;
593 H[k][j] = H[k][j] - p * x;
594 H[k + 1][j] = H[k + 1][j] - p * y;
599 for (
int i = 0; i <= std::min(n1, k + 3); i++)
601 p = x * H[i][k] + y * H[i][k + 1];
604 p = p + z * H[i][k + 2];
605 H[i][k + 2] = H[i][k + 2] - p * r;
607 H[i][k] = H[i][k] - p;
608 H[i][k + 1] = H[i][k + 1] - p * q;
613 for (
int i = low; i <= high; i++)
615 p = x * V[i][k] + y * V[i][k + 1];
618 p = p + z * V[i][k + 2];
619 V[i][k + 2] = V[i][k + 2] - p * r;
621 V[i][k] = V[i][k] - p;
622 V[i][k + 1] = V[i][k + 1] - p * q;
636 for (n1 = nn - 1; n1 >= 0; n1--)
647 for (
int i = n1 - 1; i >= 0; i--)
651 for (
int j = l; j <= n1; j++)
653 r = r + H[i][j] * H[j][n1];
680 q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
681 t = (x * s - z * r) / q;
683 if (std::abs(x) > std::abs(z))
685 H[i + 1][n1] = (-r - w * t) / x;
689 H[i + 1][n1] = (-s - y * t) / z;
695 t = std::abs(H[i][n1]);
696 if ((
eps * t) * t > 1)
698 for (
int j = i; j <= n1; j++)
700 H[j][n1] = H[j][n1] / t;
713 if (std::abs(H[n1][n1 - 1]) > std::abs(H[n1 - 1][n1]))
715 H[n1 - 1][n1 - 1] = q / H[n1][n1 - 1];
716 H[n1 - 1][n1] = -(H[n1][n1] - p) / H[n1][n1 - 1];
720 cdiv(0.0, -H[n1 - 1][n1], H[n1 - 1][n1 - 1] - p, q);
721 H[n1 - 1][n1 - 1] = cdivr;
722 H[n1 - 1][n1] = cdivi;
726 for (
int i = n1 - 2; i >= 0; i--)
731 for (
int j = l; j <= n1; j++)
733 ra = ra + H[i][j] * H[j][n1 - 1];
734 sa = sa + H[i][j] * H[j][n1];
749 cdiv(-ra, -sa, w, q);
750 H[i][n1 - 1] = cdivr;
760 (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
761 double vi = (d[i] - p) * 2.0 * q;
762 if (vr == 0.0 && vi == 0.0)
765 (std::abs(w) + std::abs(q) + std::abs(x) +
766 std::abs(y) + std::abs(z));
769 x * r - z * ra + q * sa,
770 x * s - z * sa - q * ra, vr, vi);
771 H[i][n1 - 1] = cdivr;
773 if (std::abs(x) > (std::abs(z) + std::abs(q)))
776 (-ra - w * H[i][n1 - 1] + q * H[i][n1]) / x;
778 (-sa - w * H[i][n1] - q * H[i][n1 - 1]) / x;
783 -r - y * H[i][n1 - 1], -s - y * H[i][n1], z,
785 H[i + 1][n1 - 1] = cdivr;
786 H[i + 1][n1] = cdivi;
793 std::abs(H[i][n1 - 1]), std::abs(H[i][n1]));
794 if ((
eps * t) * t > 1)
796 for (
int j = i; j <= n1; j++)
798 H[j][n1 - 1] = H[j][n1 - 1] / t;
799 H[j][n1] = H[j][n1] / t;
809 for (
int i = 0; i < nn; i++)
811 if (i < low || i > high)
813 for (
int j = i; j < nn; j++)
822 for (
int j = nn - 1; j >= low; j--)
824 for (
int i = low; i <= high; i++)
827 for (
int k = low; k <= std::min(j, high); k++)
829 z = z + V[i][k] * H[k][j];
849 for (
int m = low + 1; m <= high - 1; m++)
854 for (
int i = m; i <= high; i++)
856 scale = scale + std::abs(H[i][m - 1]);
863 for (
int i = high; i >= m; i--)
865 ort[i] = H[i][m - 1] / scale;
866 h += ort[i] * ort[i];
868 double g = std::sqrt(h);
879 for (
int j = m; j < n; j++)
882 for (
int i = high; i >= m; i--)
884 f += ort[i] * H[i][j];
887 for (
int i = m; i <= high; i++)
889 H[i][j] -= f * ort[i];
893 for (
int i = 0; i <= high; i++)
896 for (
int j = high; j >= m; j--)
898 f += ort[j] * H[i][j];
901 for (
int j = m; j <= high; j++)
903 H[i][j] -= f * ort[j];
906 ort[m] = scale * ort[m];
907 H[m][m - 1] = scale * g;
913 for (
int i = 0; i < n; i++)
915 for (
int j = 0; j < n; j++)
917 V[i][j] = (i == j ? 1.0 : 0.0);
921 for (
int m = high - 1; m >= low + 1; m--)
923 if (H[m][m - 1] != 0.0)
925 for (
int i = m + 1; i <= high; i++)
927 ort[i] = H[i][m - 1];
929 for (
int j = m; j <= high; j++)
932 for (
int i = m; i <= high; i++)
934 g += ort[i] * V[i][j];
937 g = (g / ort[m]) / H[m][m - 1];
938 for (
int i = m; i <= high; i++)
940 V[i][j] += g * ort[i];
956 for (
int i = 0; i < n; i++)
971 V = alloc_2d<double>(n, n, 0.0);
972 d = alloc_1d<double>(n);
973 e = alloc_1d<double>(n);
974 ort = alloc_1d<double>(n);
980 _eigenvalues.create(1, n, CV_64FC1);
981 for (
int i = 0; i < n; i++)
983 _eigenvalues.at<
double>(0, i) = d[i];
986 _eigenvectors.create(n, n, CV_64FC1);
987 for (
int i = 0; i < n; i++)
988 for (
int j = 0; j < n; j++)
989 _eigenvectors.at<
double>(i, j) = V[i][j];
996 EigenvalueDecomposition() =
default;
1003 EigenvalueDecomposition(cv::InputArray src) { compute(src); }
1009 void compute(cv::InputArray src)
1019 src.getMat().convertTo(tmp, CV_64FC1);
1023 this->H = alloc_2d<double>(n, n);
1025 for (
int i = 0; i < tmp.rows; i++)
1027 for (
int j = 0; j < tmp.cols; j++)
1029 this->H[i][j] = tmp.at<
double>(i, j);
1040 ~EigenvalueDecomposition() =
default;
1045 cv::Mat eigenvalues() {
return _eigenvalues; }
1050 cv::Mat eigenvectors() {
return _eigenvectors; }
1059 #endif // OPENCV_Check bool is_empty(const cv::Mat *v)
Check for negative values in vector v.
bool compute_pose(cv::Mat &R, cv::Mat &t)
OpenCV function for computing pose.
void build_coeff_matrix(const cv::Mat &pp, cv::Mat &Mtilde, cv::Mat &D)
Build the Maucaulay matrix co-efficients.
Perspective n Point (PnP) Algorithms toolkit for MRPT mrpt_vision_grp.
void fill_coeff(const cv::Mat *D)
Fill the hessian functions.
std::vector< double > f1coeff
number of input points
cv::Mat roty(const double t)
Rotation matrix along y-axis by angle t.
std::vector< double > f2coeff
void compute_eigenvec(const cv::Mat &Mtilde, cv::Mat &eigenval_real, cv::Mat &eigenval_imag, cv::Mat &eigenvec_real, cv::Mat &eigenvec_imag)
Eigen Value Decomposition.
std::vector< cv::Mat > t_est_
cv::Mat rotz(const double t)
Rotation matrix along z-axis by angle t.
std::vector< cv::Mat > C_est_
coefficient for coefficients matrix
std::vector< double > cost_
std::vector< double > f3coeff
cv::Mat cayley_LS_M(const std::vector< double > &a, const std::vector< double > &b, const std::vector< double > &c, const std::vector< double > &u)
Fill the Maucaulay matrix with co-efficients.
cv::Mat Hessian(const double s[])
Compute the Hessian matrix for the polynomial co-efficient vector s.
double cost__
optimal found solution
cv::Mat rotx(const double t)
Rotation matrix along x-axis by angle t.
cv::Mat LeftMultVec(const cv::Mat &v)
Create a matrix from vector.
cv::Mat mean(const cv::Mat &M)
Column-wise mean of matrix M.
cv::Mat cayley2rotbar(const cv::Mat &s)
Cayley parameters to Rotation Matrix.
void run_kernel(const cv::Mat &pp)
Main function to run DLS-PnP.
void init_points(const cv::Mat &opoints, const cv::Mat &ipoints)
Initialization of object points and image points.
dls(const cv::Mat &opoints, const cv::Mat &ipoints)
Constructor for DLS class.
bool positive_eigenvalues(const cv::Mat *eigenvalues)
check for positive eigenvalues
CONTAINER::Scalar norm(const CONTAINER &v)
cv::Mat skewsymm(const cv::Mat *X1)
Create a skwy-symmetric matrix from a vector.
cv::Mat C_est__
optimal candidates