00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <qvros.h>
00026
00027 #include <ros/ros.h>
00028 #include <sba/sba.h>
00029 #include <sba/sba_file_io.h>
00030 #include <sba/visualization.h>
00031 #include <visualization_msgs/Marker.h>
00032 #include <time.h>
00033 #include <map>
00034 #include <qvsfm.h>
00035
00036 using namespace sba;
00037 using namespace std;
00038 using namespace Eigen;
00039 using namespace frame_common;
00040
00041 #include <QTime>
00042
00043
00044 int initReconstructionToSysSBA( SysSBA& sbaout,
00045 const QList<QVCameraPose> &cameraPoses,
00046 const QList<QV3DPointF> &points3D,
00047 const QList< QHash< int, QPointF> > &pointsProjections)
00048 {
00049 const int ncams = cameraPoses.count();
00050 const int npts = points3D.count();
00051
00052 for (int i=0; i<ncams; i++)
00053 {
00054
00055
00056 CamParams cpars = { -1.0, -1.0, 0, 0, 0 };
00057
00058
00059 const QVCameraPose &cameraPose = cameraPoses[i];
00060 const QVQuaternion q = (QVQuaternion(1.0, 0.0, 0.0, 0.0) * cameraPose.getOrientation()).inverse();
00061 Quaternion<double> frq;
00062 frq.x() = q.i();
00063 frq.y() = q.j();
00064 frq.z() = q.k();
00065 frq.w() = q.real();
00066
00067
00068 const QV3DPointF c = cameraPose.getCenter();
00069
00070 Vector4d frt;
00071 frt[0] = c.x();
00072 frt[1] = c.y();
00073 frt[2] = c.z();
00074 frt[3] = 1.0;
00075
00076 sbaout.addNode(frt, frq, cpars);
00077 }
00078
00079
00080 for (int i=0; i<npts; i++)
00081 {
00082 const QV3DPointF p = points3D[i];
00083 Point pt;
00084 pt[0] = p.x();
00085 pt[1] = p.y();
00086 pt[2] = p.z();
00087 pt[3] = 1;
00088
00089 sbaout.addPoint(pt);
00090 }
00091
00092 sbaout.useLocalAngles = true;
00093 sbaout.nFixed = 1;
00094
00095
00096 for (int numPoint=0; numPoint<npts; numPoint++)
00097 {
00098
00099 const QHash< int, QPointF> &projections = pointsProjections[numPoint];
00100 foreach(int numCam, projections.keys())
00101 {
00102 const QPointF p = projections[numCam];
00103 Vector2d pt;
00104 pt[0] = p.x();
00105 pt[1] = -p.y();
00106 sbaout.addMonoProj(numCam,numPoint,pt);
00107 }
00108 }
00109 return 0;
00110 }
00111
00112
00113 int recoverReconstructionFromSysSBA(SysSBA &sbain, QList<QVCameraPose> &cameraPoses, QList<QV3DPointF> &points3D, QList< QHash< int, QPointF> > &pointsProjections)
00114 {
00115 unsigned int i = 0;
00116
00117
00118 Matrix3d m180x;
00119 m180x << 1, 0, 0, 0, -1, 0, 0, 0, -1;
00120
00121
00122 for (i = 0; i < sbain.nodes.size(); i++)
00123 {
00124 Quaternion<double> quat(sbain.nodes[i].qrot);
00125 quat.normalize();
00126 Matrix3d rotmat = m180x * quat.toRotationMatrix().transpose();
00127 Matrix3d &Kcam = sbain.nodes[i].Kcam;
00128
00129
00130
00131
00132 QVMatrix R(3,3), K(3,3);
00133 for(int idx = 0; idx < 3; idx++)
00134 for(int jdx = 0; jdx < 3; jdx++)
00135 {
00136 R(idx,jdx) = rotmat(idx,jdx);
00137 K(idx,jdx) = Kcam(idx, jdx);
00138 }
00139 K(2,2) = -K(2,2);
00140
00141 QV3DPointF transX( sbain.nodes[i].trans(0,0),
00142 sbain.nodes[i].trans(1,0),
00143 sbain.nodes[i].trans(2,0) );
00144
00145 transX = -R * transX;
00146
00147 const double errorK = ( QVMatrix::identity(3) + K ).norm2();
00148 if (errorK != 0.0)
00149 std::cout << "**** ERROR: sSBA changed the intrinsic camera parameters." << std::endl;
00150
00151
00152 cameraPoses << QVEuclideanMapping3(QVQuaternion(R), transX);
00153 }
00154
00155
00156 for (i = 0; i < sbain.tracks.size(); i++)
00157 {
00158
00159 points3D << QV3DPointF(sbain.tracks[i].point(0), sbain.tracks[i].point(1), sbain.tracks[i].point(2));
00160 ProjMap &prjs = sbain.tracks[i].projections;
00161 pointsProjections << QHash< int, QPointF>();
00162
00163
00164 for(ProjMap::iterator itr = prjs.begin(); itr != prjs.end(); itr++)
00165 {
00166 Proj &prj = itr->second;
00167
00168 Node &node = sbain.nodes[prj.ndi];
00169
00170 double cx = node.Kcam(0, 2);
00171 double cy = node.Kcam(1, 2);
00172 double coorX = prj.kp(0)-cx;
00173 double coorY = -(prj.kp(1)-cy);
00174
00175 pointsProjections[i][prj.ndi] = QPointF(coorX, coorY);
00176 }
00177 }
00178
00179 return 0;
00180 }
00181
00182 int sSBAOptimization( const QList<QVCameraPose> &cameraPoses,
00183 const QList<QV3DPointF> &points3D,
00184 const QList< QHash<int, QPointF> > &pointsProjections,
00185 QList<QVCameraPose> &refinedCameraPoses,
00186 QList<QV3DPointF> &refinedPoints3D,
00187 int &time_sSBA,
00188 const int numIters,
00189 const double lambda,
00190 const int useCSparse,
00191 const int numFixedCameras,
00192 const double initTolCG,
00193 const int maxItersCG
00194 )
00195 {
00196 Q_ASSERT(not testCheirality(cameraPoses, pointsProjections));
00197
00198
00199 SysSBA sys;
00200 initReconstructionToSysSBA(sys, cameraPoses, points3D, pointsProjections);
00201
00202 sys.nFixed = numFixedCameras;
00203
00204
00205
00206
00207
00208 QTime time;
00209 time.start();
00210 const int numPerformedIters = sys.doSBA(numIters, lambda, useCSparse, initTolCG, maxItersCG);
00211 time_sSBA = time.elapsed();
00212
00213 refinedPoints3D.clear();
00214 refinedCameraPoses.clear();
00215
00216 QList< QHash< int, QPointF> > refinedPointsProjections;
00217 recoverReconstructionFromSysSBA(sys, refinedCameraPoses, refinedPoints3D, refinedPointsProjections);
00218
00219 #ifdef DEBUG
00220 if (refinedPointsProjections != pointsProjections)
00221 {
00222 std::cout << "---------- Lambda ERROR x343432----------------------------------" << std::endl;
00223 exit(0);
00224 }
00225 #endif
00226
00227 return numPerformedIters;
00228 }
00229
00230
00231