Homography33.cc
Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #include <iostream>
00004 
00005 #include <Eigen/Dense>
00006 
00007 #include <opencv2/opencv.hpp>
00008 
00009 #include "Homography33.h"
00010 
00011 Homography33::Homography33(const std::pair<float,float> &opticalCenter) : cxy(opticalCenter), fA(), H(), valid(false) {
00012   fA.setZero();
00013   H.setZero();
00014 }
00015 
00016 Eigen::Matrix3d& Homography33::getH() {
00017   compute();
00018   return H;
00019 }
00020 
00021 #ifdef STABLE_H
00022 void Homography33::setCorrespondences(const std::vector< std::pair<float,float> > &sPts,
00023                                       const std::vector< std::pair<float,float> > &dPts) {
00024   valid = false;
00025   srcPts = sPts;
00026   dstPts = dPts;
00027 }
00028 #else
00029 void Homography33::addCorrespondence(float worldx, float worldy, float imagex, float imagey) {
00030   valid = false;
00031   imagex -= cxy.first;
00032   imagey -= cxy.second;
00033 
00034   /* Here are the rows of matrix A.  We will compute A'*A
00035    * A[3*i+0][3] = -worldxyh[i][0]*imagexy[i][2];
00036    * A[3*i+0][4] = -worldxyh[i][1]*imagexy[i][2];
00037    * A[3*i+0][5] = -worldxyh[i][2]*imagexy[i][2];
00038    * A[3*i+0][6] =  worldxyh[i][0]*imagexy[i][1];
00039    * A[3*i+0][7] =  worldxyh[i][1]*imagexy[i][1];
00040    * A[3*i+0][8] =  worldxyh[i][2]*imagexy[i][1];
00041    *       
00042    * A[3*i+1][0] =  worldxyh[i][0]*imagexy[i][2];
00043    * A[3*i+1][1] =  worldxyh[i][1]*imagexy[i][2];
00044    * A[3*i+1][2] =  worldxyh[i][2]*imagexy[i][2];
00045    * A[3*i+1][6] = -worldxyh[i][0]*imagexy[i][0];
00046    * A[3*i+1][7] = -worldxyh[i][1]*imagexy[i][0];
00047    * A[3*i+1][8] = -worldxyh[i][2]*imagexy[i][0];
00048    *
00049    * A[3*i+2][0] = -worldxyh[i][0]*imagexy[i][1];
00050    * A[3*i+2][1] = -worldxyh[i][1]*imagexy[i][1];
00051    * A[3*i+2][2] = -worldxyh[i][2]*imagexy[i][1];
00052    * A[3*i+2][3] =  worldxyh[i][0]*imagexy[i][0];
00053    * A[3*i+2][4] =  worldxyh[i][1]*imagexy[i][0];
00054    * A[3*i+2][5] =  worldxyh[i][2]*imagexy[i][0];
00055    */
00056 
00057   // only update upper-right. A'A is symmetric, we'll finish the lower left later.
00058   float a03 = -worldx;
00059   float a04 = -worldy;
00060   float a05 = -1;
00061   float a06 = worldx*imagey;
00062   float a07 = worldy*imagey;
00063   float a08 = imagey;
00064 
00065   fA(3, 3) += a03*a03;
00066   fA(3, 4) += a03*a04;
00067   fA(3, 5) += a03*a05;
00068   fA(3, 6) += a03*a06;
00069   fA(3, 7) += a03*a07;
00070   fA(3, 8) += a03*a08;
00071 
00072   fA(4, 4) += a04*a04;
00073   fA(4, 5) += a04*a05;
00074   fA(4, 6) += a04*a06;
00075   fA(4, 7) += a04*a07;
00076   fA(4, 8) += a04*a08;
00077 
00078   fA(5, 5) += a05*a05;
00079   fA(5, 6) += a05*a06;
00080   fA(5, 7) += a05*a07;
00081   fA(5, 8) += a05*a08;
00082 
00083   fA(6, 6) += a06*a06;
00084   fA(6, 7) += a06*a07;
00085   fA(6, 8) += a06*a08;
00086 
00087   fA(7, 7) += a07*a07;
00088   fA(7, 8) += a07*a08;
00089 
00090   fA(8, 8) += a08*a08;
00091 
00092   float a10 = worldx;
00093   float a11 = worldy;
00094   float a12 = 1;
00095   float a16 = -worldx*imagex;
00096   float a17 = -worldy*imagex;
00097   float a18 = -imagex;
00098 
00099   fA(0, 0) += a10*a10;
00100   fA(0, 1) += a10*a11;
00101   fA(0, 2) += a10*a12;
00102   fA(0, 6) += a10*a16;
00103   fA(0, 7) += a10*a17;
00104   fA(0, 8) += a10*a18;
00105 
00106   fA(1, 1) += a11*a11;
00107   fA(1, 2) += a11*a12;
00108   fA(1, 6) += a11*a16;
00109   fA(1, 7) += a11*a17;
00110   fA(1, 8) += a11*a18;
00111 
00112   fA(2, 2) += a12*a12;
00113   fA(2, 6) += a12*a16;
00114   fA(2, 7) += a12*a17;
00115   fA(2, 8) += a12*a18;
00116 
00117   fA(6, 6) += a16*a16;
00118   fA(6, 7) += a16*a17;
00119   fA(6, 8) += a16*a18;
00120 
00121   fA(7, 7) += a17*a17;
00122   fA(7, 8) += a17*a18;
00123 
00124   fA(8, 8) += a18*a18;
00125 
00126   float a20 = -worldx*imagey;
00127   float a21 = -worldy*imagey;
00128   float a22 = -imagey;
00129   float a23 = worldx*imagex;
00130   float a24 = worldy*imagex;
00131   float a25 = imagex;
00132 
00133   fA(0, 0) += a20*a20;
00134   fA(0, 1) += a20*a21;
00135   fA(0, 2) += a20*a22;
00136   fA(0, 3) += a20*a23;
00137   fA(0, 4) += a20*a24;
00138   fA(0, 5) += a20*a25;
00139 
00140   fA(1, 1) += a21*a21;
00141   fA(1, 2) += a21*a22;
00142   fA(1, 3) += a21*a23;
00143   fA(1, 4) += a21*a24;
00144   fA(1, 5) += a21*a25;
00145 
00146   fA(2, 2) += a22*a22;
00147   fA(2, 3) += a22*a23;
00148   fA(2, 4) += a22*a24;
00149   fA(2, 5) += a22*a25;
00150 
00151   fA(3, 3) += a23*a23;
00152   fA(3, 4) += a23*a24;
00153   fA(3, 5) += a23*a25;
00154 
00155   fA(4, 4) += a24*a24;
00156   fA(4, 5) += a24*a25;
00157 
00158   fA(5, 5) += a25*a25;
00159 }
00160 #endif
00161 
00162 #ifdef STABLE_H
00163 void Homography33::compute() {
00164   if ( valid ) return;
00165 
00166   std::vector<cv::Point2f> sPts;
00167   std::vector<cv::Point2f> dPts;
00168   for (int i=0; i<4; i++) {
00169     sPts.push_back(cv::Point2f(srcPts[i].first, srcPts[i].second));
00170   }
00171   for (int i=0; i<4; i++) {
00172     dPts.push_back(cv::Point2f(dstPts[i].first - cxy.first, dstPts[i].second - cxy.second));
00173   }
00174   cv::Mat homography = cv::findHomography(sPts, dPts);
00175   for (int c=0; c<3; c++) {
00176     for (int r=0; r<3; r++) {
00177       H(r,c) = homography.at<double>(r,c);
00178     }
00179   }
00180 
00181   valid = true;
00182 }
00183 #else
00184 void Homography33::compute() {
00185   if ( valid ) return;
00186 
00187   // make symmetric
00188   for (int i = 0; i < 9; i++)
00189     for (int j = i+1; j < 9; j++)
00190       fA(j,i) = fA(i,j);
00191 
00192   Eigen::JacobiSVD<Eigen::MatrixXd> svd(fA, Eigen::ComputeFullU | Eigen::ComputeFullV);
00193   Eigen::MatrixXd eigV = svd.matrixV();
00194 
00195   for (int i = 0; i < 3; i++) {
00196     for (int j = 0; j < 3; j++) {
00197       H(i,j) = eigV(i*3+j, eigV.cols()-1);
00198     }
00199   }
00200 
00201   valid = true;
00202 }
00203 #endif
00204 
00205 std::pair<float,float> Homography33::project(float worldx, float worldy) {
00206   compute();
00207 
00208   std::pair<float,float> ixy;
00209   ixy.first = H(0,0)*worldx + H(0,1)*worldy + H(0,2);
00210   ixy.second = H(1,0)*worldx + H(1,1)*worldy + H(1,2);
00211   float z = H(2,0)*worldx + H(2,1)*worldy + H(2,2);
00212   ixy.first = ixy.first/z + cxy.first;
00213   ixy.second = ixy.second/z + cxy.second;
00214   return ixy;
00215 }
00216 


apriltags
Author(s): Michael Kaess, Hordur Johannson
autogenerated on Thu Jun 6 2019 20:53:23