#include <visp/vpColVector.h>
#include <visp/vpHomogeneousMatrix.h>
#include <visp/vpMatrix.h>
vpMatrix homography_dlt(const std::vector< vpColVector > &x1, const std::vector< vpColVector > &x2)
{
int npoints = (int)x1.size();
vpMatrix A(2*npoints, 9, 0.);
if (npoints == 4)
A.resize(2*npoints+1, 9);
for(int i = 0; i < npoints; i++) {
A[2*i][3] = -x1[i][0];
A[2*i][4] = -x1[i][1];
A[2*i][5] = -x1[i][2];
A[2*i][6] = x2[i][1] * x1[i][0];
A[2*i][7] = x2[i][1] * x1[i][1];
A[2*i][8] = x2[i][1] * x1[i][2];
A[2*i+1][0] = x1[i][0];
A[2*i+1][1] = x1[i][1];
A[2*i+1][2] = x1[i][2];
A[2*i+1][6] = -x2[i][0] * x1[i][0];
A[2*i+1][7] = -x2[i][0] * x1[i][1];
A[2*i+1][8] = -x2[i][0] * x1[i][2];
}
if (npoints == 4) {
for (int i=0; i < 9; i ++) {
A[2*npoints][i] = 0;
}
}
vpColVector D;
vpMatrix V;
A.svd(D, V);
double smallestSv = D[0];
unsigned int indexSmallestSv = 0 ;
for (unsigned int i = 1; i < D.size(); i++) {
if ((D[i] < smallestSv) ) {
smallestSv = D[i];
indexSmallestSv = i ;
}
}
#if VISP_VERSION_INT >= VP_VERSION_INT(2, 10, 0)
vpColVector h = V.getCol(indexSmallestSv);
#else
vpColVector h = V.column(indexSmallestSv + 1);
#endif
if (h[8] < 0)
h *=-1;
vpMatrix _2H1(3, 3);
for (int i = 0 ; i < 3 ; i++)
for (int j = 0 ; j < 3 ; j++)
_2H1[i][j] = h[3*i+j];
return _2H1;
}
int main()
{
int npoints = 4;
std::vector< vpColVector > x1(npoints);
std::vector< vpColVector > x2(npoints);
std::vector< vpColVector > wX(npoints);
std::vector< vpColVector > c1X(npoints);
std::vector< vpColVector > c2X(npoints);
for (int i = 0; i < npoints; i++) {
x1[i].resize(3);
x2[i].resize(3);
wX[i].resize(4);
c1X[i].resize(4);
c2X[i].resize(4);
}
vpHomogeneousMatrix c1Tw_truth(-0.1, 0.1, 1.2, vpMath::rad(5), vpMath::rad(0), vpMath::rad(45));
vpHomogeneousMatrix c2Tc1(0.01, 0.01, 0.2, vpMath::rad(0), vpMath::rad(3), vpMath::rad(5));
double L = 0.2;
wX[0][0] = -L; wX[0][1] = -L; wX[0][2] = 0; wX[0][3] = 1;
wX[1][0] = 2*L; wX[1][1] = -L; wX[1][2] = 0; wX[1][3] = 1;
wX[2][0] = L; wX[2][1] = L; wX[2][2] = 0; wX[2][3] = 1;
wX[3][0] = -L; wX[3][1] = L; wX[3][2] = 0; wX[3][3] = 1;
for(int i = 0; i < npoints; i++) {
c1X[i] = c1Tw_truth * wX[i];
x1[i][0] = c1X[i][0] / c1X[i][2];
x1[i][1] = c1X[i][1] / c1X[i][2];
x1[i][2] = 1;
c2X[i] = c2Tc1 * c1Tw_truth * wX[i];
x2[i][0] = c2X[i][0] / c2X[i][2];
x2[i][1] = c2X[i][1] / c2X[i][2];
x2[i][2] = 1;
}
vpMatrix _2H1 = homography_dlt(x1, x2);
std::cout << "2H1 (computed with DLT):\n" << _2H1 << std::endl;
return 0;
}