00001
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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
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
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