00001
00007 #ifndef P_HOMOGRAPHY_HH
00008 #define P_HOMOGRAPHY_HH
00009
00010 #include <iostream>
00011 #include <float.h>
00012
00013
00014 #include <opencv2/opencv.hpp>
00015 #include <blort/Recognizer3D/Vector2.hh>
00016 #include <blort/Recognizer3D/Array.hh>
00017 #include <blort/Recognizer3D/PNamespace.hh>
00018 #include <blort/Recognizer3D/Except.hh>
00019 #include <blort/Recognizer3D/homest.h>
00020 #include <blort/Recognizer3D/Math.hh>
00021 #include <blort/Recognizer3D/SMatrix.hh>
00022 #include <blort/Recognizer3D/PoseCv.hh>
00023
00024 namespace P
00025 {
00026
00027 class Homography
00028 {
00029 private:
00030 Array<Vector2> pts1, pts2;
00031 Array<Vector2> lns1, lns2;
00032
00033 unsigned lastPt;
00034 unsigned lastLn;
00035
00036 double *T1, *invT;
00037
00038 void NormalizePts(Array<Vector2> &in, unsigned numPts, Array<Vector2> &out, double T[9]);
00039 void NormalizeLns(double T[9], Array<Vector2> &in, unsigned numLns, Array<Vector2> &out);
00040 void SetDataMatrixPts(Array<Vector2> &pts1, Array<Vector2> &pts2, unsigned numPts, unsigned start, CvMat *A);
00041 void SetDataMatrixLns(Array<Vector2> &lns1, Array<Vector2> &lns2, unsigned numLns, unsigned start, CvMat *A);
00042 void NormalizeH(double H[9], double T1[9], double T2[9], double nH[9]);
00043 void DenormalizeH(double nH[9], double T1[9], double T2[9], double H[9]);
00044 void GetRandIdx(unsigned size, unsigned num, P::Array<unsigned> &idx);
00045 bool SolveHomography(CvMat *A, CvMat *W, CvMat *Ut, CvMat *Vt, double H[9]);
00046 void CountInlierPts(double H[9], double thr, int &inl);
00047 void CountInlierLns(double H[9], double thr, double thrAngle, int &inl);
00048 void SetDataMatrix(double *d, double H[9], double thr, double thrAngle, int &numInl);
00049
00050
00051 inline void InsertPointCoeff(Vector2 &pt1, Vector2 &pt2, double *d);
00052 inline void InsertLineCoeff(Vector2 &ln1, Vector2 &ln2, double *d);
00053
00054
00055
00056 public:
00057 Array<int> outl;
00058 Array<int> outlLns;
00059
00060 Homography();
00061 Homography(unsigned nbPoints, unsigned nbLines=0);
00062 ~Homography();
00063
00064 bool EstimateHom(double H[9], int &nbOutliers, double inlPcent=.8, bool returnOutl=false, int normalize=1, int NLrefine=HOMEST_SYM_XFER_ERROR, int verbose=1);
00065 bool EstimateAff(double H[9], int &nbOutliers, double inlPcent=.8, bool returnOutl=false, int normalize=1, int verbose=1);
00066
00067 bool ComputeHomLS(double H[9], bool normalize=true);
00068 bool ComputeHomRobustLS(double H[9], bool normalize=true, double thrInlier=1., double thrAngle=1.);
00069 bool ComputeHom(double a1[2], double a2[2], double a3[2], double a4[2],
00070 double b1[2], double b2[2], double b3[2], double b4[2],
00071 double H[9]);
00072 bool ComputeAff(double a1[2], double a2[2], double a3[2],
00073 double b1[2], double b2[2], double b3[2],
00074 double H[9]);
00075
00076 inline void InsertNext(double pt1[2], double pt2[2]);
00077 inline void InsertNextPt(double pt1[2], double pt2[2]);
00078 inline void InsertNextLn(double ln1[2], double ln2[2]);
00079 inline void InsertNextLn(double a1[2], double b1[2], double a2[2], double b2[2]);
00080 inline void SetFirst();
00081 inline void Resize(unsigned nbPoints, unsigned nbLines=0);
00082
00083 inline void LinePts2Para(double p1[2], double p2[2], double l[3]);
00084 };
00085
00086
00087 inline void MapPoint(double xin, double yin, double H[9], double &xout, double &yout);
00088 inline void MapPoint(double in[2], double H[9], double out[2]);
00089 inline void GetPosScaleAngle( double x, double y, double H[9], double &xr, double &yr, double &scale, double &angle);
00090
00091
00092
00093
00094
00095
00099 inline void Homography::InsertPointCoeff(Vector2 &pt1, Vector2 &pt2, double *d)
00100 {
00101 double t1, t2, t3, t4;
00102
00103 t1 = pt1.x;
00104 t2 = pt1.y;
00105 t3 = pt2.x;
00106 t4 = pt2.y;
00107
00108 d[0] = -t1;
00109 d[1] = -t2;
00110 d[2] = -1.0;
00111 d[3] = 0.0;
00112 d[4] = 0.0;
00113 d[5] = 0.0;
00114 d[6] = t3*t1;
00115 d[7] = t2*t3;
00116 d[8] = t3;
00117 d[9] = 0.0;
00118 d[10] = 0.0;
00119 d[11] = 0.0;
00120 d[12] = d[0];
00121 d[13] = d[1];
00122 d[14] = -1.0;
00123 d[15] = t4*t1;
00124 d[16] = t4*t2;
00125 d[17] = t4;
00126 }
00127
00131 inline void Homography::InsertLineCoeff(Vector2 &ln1, Vector2 &ln2, double *d)
00132 {
00133 double t1, t2, t3, t4;
00134
00135 t1 = ln1.x;
00136 t2 = ln1.y;
00137 t3 = ln2.x;
00138 t4 = ln2.y;
00139
00140 d[0] = -t3;
00141 d[1] = 0.;
00142 d[2] = t3*t1;
00143 d[3] = -t4;
00144 d[4] = 0.;
00145 d[5] = t4*t1;
00146 d[6] = -1;
00147 d[7] = 0.;
00148 d[8] = t1;
00149 d[9] = 0.;
00150 d[10] = -t3;
00151 d[11] = t3*t2;
00152 d[12] = 0.;
00153 d[13] = -t4;
00154 d[14] = t4*t2;
00155 d[15] = 0.;
00156 d[16] = -1;
00157 d[17] = t2;
00158 }
00159
00163 inline void Homography::Resize(unsigned nbPoints, unsigned nbLines)
00164 {
00165 if (nbPoints>0)
00166 {
00167 pts1.Resize(nbPoints);
00168 pts2.Resize(nbPoints);
00169 }
00170 if (nbLines>0)
00171 {
00172 lns1.Resize(nbLines);
00173 lns2.Resize(nbLines);
00174 }
00175 lastPt=0;
00176 lastLn=0;
00177 }
00178
00182 inline void Homography::SetFirst()
00183 {
00184 lastPt = 0;
00185 lastLn = 0;
00186 }
00187
00191 inline void Homography::InsertNext(double pt1[2], double pt2[2])
00192 {
00193 if (lastPt<pts1.Size())
00194 {
00195 pts1[lastPt].x = pt1[0];
00196 pts1[lastPt].y = pt1[1];
00197 pts2[lastPt].x = pt2[0];
00198 pts2[lastPt].y = pt2[1];
00199 lastPt++;
00200 }
00201 else
00202 {
00203 pts1.PushBack(Vector2(pt1[0],pt1[1]));
00204 pts2.PushBack(Vector2(pt2[0],pt2[1]));
00205 lastPt++;
00206 }
00207 }
00208
00212 inline void Homography::InsertNextPt(double pt1[2], double pt2[2])
00213 {
00214 if (lastPt<pts1.Size())
00215 {
00216 pts1[lastPt].x = pt1[0];
00217 pts1[lastPt].y = pt1[1];
00218 pts2[lastPt].x = pt2[0];
00219 pts2[lastPt].y = pt2[1];
00220 lastPt++;
00221 }
00222 else
00223 {
00224 pts1.PushBack(Vector2(pt1[0],pt1[1]));
00225 pts2.PushBack(Vector2(pt2[0],pt2[1]));
00226 lastPt++;
00227 }
00228 }
00229
00238 inline void Homography::InsertNextLn(double ln1[2], double ln2[2])
00239 {
00240 if (lastLn<lns1.Size())
00241 {
00242 lns1[lastLn].x = ln1[0];
00243 lns1[lastLn].y = ln1[1];
00244 lns2[lastLn].x = ln2[0];
00245 lns2[lastLn].y = ln2[1];
00246 lastLn++;
00247 }
00248 else
00249 {
00250 lns1.PushBack(Vector2(ln1[0],ln1[1]));
00251 lns2.PushBack(Vector2(ln2[0],ln2[1]));
00252 lastLn++;
00253 }
00254 }
00255
00259 inline void Homography::InsertNextLn(double a1[2], double b1[2], double a2[2], double b2[2])
00260 {
00261 double l[3];
00262
00263
00264 if (lastLn<lns1.Size())
00265 {
00266 LinePts2Para(a1,b1,l);
00267 lns1[lastLn].x = l[0]/l[2];
00268 lns1[lastLn].y = l[1]/l[2];
00269 LinePts2Para(a2,b2,l);
00270 lns2[lastLn].x = l[0]/l[2];
00271 lns2[lastLn].y = l[1]/l[2];
00272 lastLn++;
00273 }
00274 else
00275 {
00276 LinePts2Para(a1,b1,l);
00277 lns1.PushBack(Vector2(l[0]/l[2],l[1]/l[2]));
00278 LinePts2Para(a2,b2,l);
00279 lns2.PushBack(Vector2(l[0]/l[2],l[1]/l[2]));
00280 lastLn++;
00281 }
00282 }
00283
00287 inline void Homography::LinePts2Para(double p1[2], double p2[2], double l[3])
00288 {
00289 l[0] = p1[1]-p2[1];
00290 l[1] = p2[0]-p1[0];
00291 l[2] = p1[0]*p2[1] - p1[1]*p2[0];
00292 }
00293
00298 inline void MapPoint(double xin, double yin, double H[9], double &xout, double &yout)
00299 {
00300 xout = H[0]*xin + H[1]*yin + H[2];
00301 yout = H[3]*xin + H[4]*yin + H[5];
00302 double t = H[6]*xin + H[7]*yin + H[8];
00303 xout /= t;
00304 yout /= t;
00305 }
00306
00311 inline void MapPoint(double in[2], double H[9], double out[2])
00312 {
00313 out[0] = H[0]*in[0] + H[1]*in[1] + H[2];
00314 out[1] = H[3]*in[0] + H[4]*in[1] + H[5];
00315 double t = H[6]*in[0] + H[7]*in[1] + H[8];
00316 out[0] /= t;
00317 out[1] /= t;
00318 }
00319
00323 inline void GetPosScaleAngle( double x, double y, double H[9], double &xr, double &yr, double &scale, double &angle)
00324 {
00325 double x2=x+10.;
00326 double y2=y;
00327 double x2H,y2H;
00328 MapPoint(x,y,H,xr,yr);
00329 MapPoint(x2,y2,H,x2H,y2H);
00330
00331 double dxH=x2H-xr;
00332 double dyH=y2H-yr;
00333 scale=((sqrt(dxH*dxH+dyH*dyH))/10.);
00334 angle=atan2(dyH,dxH);
00335 }
00336
00337
00338
00339 }
00340
00341 #endif
00342