Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Homography.h

Go to the documentation of this file.
00001 #ifndef _HOMOGRAPHY_H_
00002 #define _HOMOGRAPHY_H_
00003 
00004 #include "Shared/newmat/newmat.h"
00005 #include "Shared/newmat/newmatap.h"
00006 #include "Shared/fmat.h"
00007 
00008 class Homography {
00009   //! The matrix that holds the correspondences
00010   fmat::Matrix<9,9> A;
00011   //! The matrix that holds the computed homography
00012   fmat::Matrix<3,3> h;
00013   //! The matrix that holds the inverse of the computed homography
00014   fmat::Matrix<3,3> hInv;
00015   
00016   //! Whether the homography is out of date with how many correspondences have been added
00017   bool isDirty;
00018   
00019 public:
00020   
00021   Homography(): A(), h(), hInv(), isDirty(true) {
00022     for(unsigned i = 0; i < 9; i++)
00023       for(unsigned j = 0; j < 9; j++)
00024         A(i,j) = 0;
00025     
00026     for(unsigned i = 0; i < 3; i++)
00027       for(unsigned j = 0; j < 3; j++) {
00028         h(i,j) = 0;
00029         hInv(i,j) = 0;
00030       }
00031   }
00032   
00033   //! Projects (x,y) to the corrected values (correctedX, correctedY) based off the homography matrix
00034   void project(float x, float y, float& correctedX, float& correctedY) {
00035     fmat::Matrix<3,3>& H = getMatrix();
00036     
00037     correctedX = H(0,0)*x + H(0,1)*y + H(0,2);
00038     correctedY = H(1,0)*x + H(1,1)*y + H(1,2);
00039     float z =    H(2,0)*x + H(2,1)*y + H(2,2);
00040     if(z == 0)
00041       z = 1;
00042     
00043     correctedX /= z;
00044     correctedY /= z;
00045   }
00046   
00047   //! Inverts (correctedX, correctedY) to the original values (x,y) from the homography matrix inverse
00048   void invertProjection(float correctedX, float correctedY, float& x, float& y) {
00049     float z;
00050     fmat::Matrix<3,3>& invH = getMatrixInverse();
00051     
00052     x = invH(0,0)*correctedX + invH(0,1)*correctedY + invH(0,2);
00053     y = invH(1,0)*correctedX + invH(1,1)*correctedY + invH(1,2);
00054     z = invH(2,0)*correctedX + invH(2,1)*correctedY + invH(2,2);
00055     
00056     x /= z;
00057     y /= z;
00058   }
00059   
00060   //! Returns the homography so far, recomputes H if out of date
00061   fmat::Matrix<3,3>& getMatrix()
00062     {
00063     if(!isDirty)
00064       return h;
00065     
00066         // make symmetric
00067         for (int i = 0; i < 9; i++)
00068             for (int j = i+1; j < 9; j++)
00069                 A(j,i) = A(i,j);
00070     
00071     NEWMAT::Matrix nmA(9,9), U, V;
00072     NEWMAT::DiagonalMatrix D;
00073     
00074     A.exportToNewmat(nmA);
00075     
00076         // compute using singular value decomposition
00077     NEWMAT::SVD(nmA,D,U,V);
00078     
00079       for (int i = 0; i < 3; i++) {
00080             for (int j = 0; j < 3; j++) {
00081                 h(i,j) = V(i*3+j+1, V.ncols());
00082       }
00083     }
00084     
00085     hInv = invert(h);
00086     
00087     isDirty = false;
00088     
00089     return h;
00090     }
00091   
00092   fmat::Matrix<3,3>& getMatrixInverse() {
00093     //Compute new data if dirty
00094     getMatrix();
00095     return hInv;
00096   }
00097   
00098   //! Adds a correspondence to the list. actualx and actualy are the corrected values, imagex and imagey are the perceived values
00099   void addCorrespondence(double actualx, double actualy, double imagex, double imagey)
00100     {
00101     isDirty = true;
00102 //    cout<<"("<<imagex<<", "<<imagey<<") -> ("<<actualx<<", "<<actualy<<")"<<endl;
00103         double a03 = -actualx;
00104         double a04 = -actualy;
00105         double a05 = -1;
00106         double a06 = actualx*imagey;
00107         double a07 = actualy*imagey;
00108         double a08 = imagey;
00109     
00110         A(3, 3) += a03*a03;
00111         A(3, 4) += a03*a04;
00112         A(3, 5) += a03*a05;
00113         A(3, 6) += a03*a06;
00114         A(3, 7) += a03*a07;
00115         A(3, 8) += a03*a08;
00116         A(4, 4) += a04*a04;
00117         A(4, 5) += a04*a05;
00118         A(4, 6) += a04*a06;
00119         A(4, 7) += a04*a07;
00120         A(4, 8) += a04*a08;
00121         A(5, 5) += a05*a05;
00122         A(5, 6) += a05*a06;
00123         A(5, 7) += a05*a07;
00124         A(5, 8) += a05*a08;
00125         A(6, 6) += a06*a06;
00126         A(6, 7) += a06*a07;
00127         A(6, 8) += a06*a08;
00128         A(7, 7) += a07*a07;
00129         A(7, 8) += a07*a08;
00130         A(8, 8) += a08*a08;
00131     
00132         double a10 = actualx;
00133         double a11 = actualy;
00134         double a12 = 1;
00135         double a16 = -actualx*imagex;
00136         double a17 = -actualy*imagex;
00137         double a18 = -imagex;
00138     
00139         A(0, 0) += a10*a10;
00140         A(0, 1) += a10*a11;
00141         A(0, 2) += a10*a12;
00142         A(0, 6) += a10*a16;
00143         A(0, 7) += a10*a17;
00144         A(0, 8) += a10*a18;
00145         A(1, 1) += a11*a11;
00146         A(1, 2) += a11*a12;
00147         A(1, 6) += a11*a16;
00148         A(1, 7) += a11*a17;
00149         A(1, 8) += a11*a18;
00150         A(2, 2) += a12*a12;
00151         A(2, 6) += a12*a16;
00152     A(2, 7) += a12*a17;
00153         A(2, 8) += a12*a18;
00154         A(6, 6) += a16*a16;
00155         A(6, 7) += a16*a17;
00156         A(6, 8) += a16*a18;
00157         A(7, 7) += a17*a17;
00158         A(7, 8) += a17*a18;
00159         A(8, 8) += a18*a18;
00160     
00161         double a20 = -actualx*imagey;
00162         double a21 = -actualy*imagey;
00163         double a22 = -imagey;
00164         double a23 = actualx*imagex;
00165         double a24 = actualy*imagex;
00166         double a25 = imagex;
00167     
00168         A(0, 0) += a20*a20;
00169         A(0, 1) += a20*a21;
00170         A(0, 2) += a20*a22;
00171         A(0, 3) += a20*a23;
00172         A(0, 4) += a20*a24;
00173         A(0, 5) += a20*a25;
00174         A(1, 1) += a21*a21;
00175         A(1, 2) += a21*a22;
00176         A(1, 3) += a21*a23;
00177         A(1, 4) += a21*a24;
00178         A(1, 5) += a21*a25;
00179         A(2, 2) += a22*a22;
00180         A(2, 3) += a22*a23;
00181         A(2, 4) += a22*a24;
00182         A(2, 5) += a22*a25;
00183         A(3, 3) += a23*a23;
00184         A(3, 4) += a23*a24;
00185         A(3, 5) += a23*a25;
00186         A(4, 4) += a24*a24;
00187         A(4, 5) += a24*a25;
00188         A(5, 5) += a25*a25;
00189     }
00190   
00191 };
00192 
00193 
00194 
00195 
00196 
00197 
00198 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:41 2016 by Doxygen 1.6.3