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
00010 fmat::Matrix<9,9> A;
00011
00012 fmat::Matrix<3,3> h;
00013
00014 fmat::Matrix<3,3> hInv;
00015
00016
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
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
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
00061 fmat::Matrix<3,3>& getMatrix()
00062 {
00063 if(!isDirty)
00064 return h;
00065
00066
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
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
00094 getMatrix();
00095 return hInv;
00096 }
00097
00098
00099 void addCorrespondence(double actualx, double actualy, double imagex, double imagey)
00100 {
00101 isDirty = true;
00102
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