⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapmaker.cc

📁 this is software for visual SLAM
💻 CC
📖 第 1 页 / 共 3 页
字号:
    }    // Add the points' 3D position  for(set<MapPoint*>::iterator it = sMapPoints.begin(); it!=sMapPoints.end(); it++)    {      int nBundleID = b.AddPoint((*it)->v3WorldPos);      mPoint_BundleID[*it] = nBundleID;      mBundleID_Point[nBundleID] = *it;    }    // Add the relevant point-in-keyframe measurements  for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)    {      if(mView_BundleID.count(mMap.vpKeyFrames[i]) == 0)	continue;            int nKF_BundleID = mView_BundleID[mMap.vpKeyFrames[i]];      for(meas_it it= mMap.vpKeyFrames[i]->mMeasurements.begin();	  it!= mMap.vpKeyFrames[i]->mMeasurements.end();	  it++)	{	  if(mPoint_BundleID.count(it->first) == 0)	    continue;	  int nPoint_BundleID = mPoint_BundleID[it->first];	  b.AddMeas(nKF_BundleID, nPoint_BundleID, it->second.v2RootPos, LevelScale(it->second.nLevel) * LevelScale(it->second.nLevel));	}    }    // Run the bundle adjuster. This returns the number of successful iterations  int nAccepted = b.Compute(&mbBundleAbortRequested);    if(nAccepted < 0)    {      // Crap: - LM Ran into a serious problem!      // This is probably because the initial stereo was messed up.      // Get rid of this map and start again!       cout << "!! MapMaker: Cholesky failure in bundle adjust. " << endl	   << "   The map is probably corrupt: Ditching the map. " << endl;      mbResetRequested = true;      return;    }  // Bundle adjustment did some updates, apply these to the map  if(nAccepted > 0)    {            for(map<MapPoint*,int>::iterator itr = mPoint_BundleID.begin();	  itr!=mPoint_BundleID.end();	  itr++)	itr->first->v3WorldPos = b.GetPoint(itr->second);            for(map<KeyFrame*,int>::iterator itr = mView_BundleID.begin();	  itr!=mView_BundleID.end();	  itr++)	itr->first->se3CfromW = b.GetCamera(itr->second);      if(bRecent)	mbBundleConverged_Recent = false;      mbBundleConverged_Full = false;    };    if(b.Converged())    {      mbBundleConverged_Recent = true;      if(!bRecent)	mbBundleConverged_Full = true;    }    mbBundleRunning = false;  mbBundleAbortRequested = false;    // Handle outlier measurements:  vector<pair<int,int> > vOutliers_PC_pair = b.GetOutlierMeasurements();  for(unsigned int i=0; i<vOutliers_PC_pair.size(); i++)    {      MapPoint *pp = mBundleID_Point[vOutliers_PC_pair[i].first];      KeyFrame *pk = mBundleID_View[vOutliers_PC_pair[i].second];      Measurement &m = pk->mMeasurements[pp];      if(pp->pMMData->GoodMeasCount() <= 2 || m.Source == Measurement::SRC_ROOT)   // Is the original source kf considered an outlier? That's bad.	pp->bBad = true;      else	{	  // Do we retry it? Depends where it came from!!	  if(m.Source == Measurement::SRC_TRACKER || m.Source == Measurement::SRC_EPIPOLAR)	    mvFailureQueue.push_back(pair<KeyFrame*,MapPoint*>(pk,pp));	  else	    pp->pMMData->sNeverRetryKFs.insert(pk);	  pk->mMeasurements.erase(pp);	  pp->pMMData->sMeasurementKFs.erase(pk);	}    }}// Mapmaker's try-to-find-a-point-in-a-keyframe code. This is used to update// data association if a bad measurement was detected, or if a point// was never searched for in a keyframe in the first place. This operates// much like the tracker! So most of the code looks just like in // TrackerData.h.bool MapMaker::ReFind_Common(KeyFrame &k, MapPoint &p){  // abort if either a measurement is already in the map, or we've  // decided that this point-kf combo is beyond redemption  if(p.pMMData->sMeasurementKFs.count(&k)     || p.pMMData->sNeverRetryKFs.count(&k))    return false;    static PatchFinder Finder;  Vector<3> v3Cam = k.se3CfromW*p.v3WorldPos;  if(v3Cam[2] < 0.001)    {      p.pMMData->sNeverRetryKFs.insert(&k);      return false;    }  Vector<2> v2ImPlane = project(v3Cam);  if(v2ImPlane* v2ImPlane > mCamera.LargestRadiusInImage() * mCamera.LargestRadiusInImage())    {      p.pMMData->sNeverRetryKFs.insert(&k);      return false;    }    Vector<2> v2Image = mCamera.Project(v2ImPlane);  if(mCamera.Invalid())    {      p.pMMData->sNeverRetryKFs.insert(&k);      return false;    }  ImageRef irImageSize = k.aLevels[0].im.size();  if(v2Image[0] < 0 || v2Image[1] < 0 || v2Image[0] > irImageSize[0] || v2Image[1] > irImageSize[1])    {      p.pMMData->sNeverRetryKFs.insert(&k);      return false;    }    Matrix<2> m2CamDerivs = mCamera.GetProjectionDerivs();  Finder.MakeTemplateCoarse(p, k.se3CfromW, m2CamDerivs);    if(Finder.TemplateBad())    {      p.pMMData->sNeverRetryKFs.insert(&k);      return false;    }    bool bFound = Finder.FindPatchCoarse(ir(v2Image), k, 4);  // Very tight search radius!  if(!bFound)    {      p.pMMData->sNeverRetryKFs.insert(&k);      return false;    }    // If we found something, generate a measurement struct and put it in the map  Measurement m;  m.nLevel = Finder.GetLevel();  m.Source = Measurement::SRC_REFIND;    if(Finder.GetLevel() > 0)    {      Finder.MakeSubPixTemplate();      Finder.IterateSubPixToConvergence(k,8);      m.v2RootPos = Finder.GetSubPixPos();      m.bSubPix = true;    }  else    {      m.v2RootPos = Finder.GetCoarsePosAsVector();      m.bSubPix = false;    };    if(k.mMeasurements.count(&p))    {      assert(0); // This should never happen, we checked for this at the start.    }  k.mMeasurements[&p] = m;  p.pMMData->sMeasurementKFs.insert(&k);  return true;}// A general data-association update for a single keyframe// Do this on a new key-frame when it's passed in by the trackerint MapMaker::ReFindInSingleKeyFrame(KeyFrame &k){  vector<MapPoint*> vToFind;  for(unsigned int i=0; i<mMap.vpPoints.size(); i++)    vToFind.push_back(mMap.vpPoints[i]);    int nFoundNow = 0;  for(unsigned int i=0; i<vToFind.size(); i++)    if(ReFind_Common(k,*vToFind[i]))      nFoundNow++;  return nFoundNow;};// When new map points are generated, they're only created from a stereo pair// this tries to make additional measurements in other KFs which they might// be in.void MapMaker::ReFindNewlyMade(){  if(mqNewQueue.empty())    return;  int nFound = 0;  int nBad = 0;  while(!mqNewQueue.empty() && mvpKeyFrameQueue.size() == 0)    {      MapPoint* pNew = mqNewQueue.front();      mqNewQueue.pop();      if(pNew->bBad)	{	  nBad++;	  continue;	}      for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)	if(ReFind_Common(*mMap.vpKeyFrames[i], *pNew))	  nFound++;    }};// Dud measurements get a second chance.void MapMaker::ReFindFromFailureQueue(){  if(mvFailureQueue.size() == 0)    return;  sort(mvFailureQueue.begin(), mvFailureQueue.end());  vector<pair<KeyFrame*, MapPoint*> >::iterator it;  int nFound=0;  for(it = mvFailureQueue.begin(); it!=mvFailureQueue.end(); it++)    if(ReFind_Common(*it->first, *it->second))      nFound++;    mvFailureQueue.erase(mvFailureQueue.begin(), it);};// Is the tracker's camera pose in cloud-cuckoo land?bool MapMaker::IsDistanceToNearestKeyFrameExcessive(KeyFrame &kCurrent){  return DistToNearestKeyFrame(kCurrent) > mdWiggleScale * 10.0;}// Find a dominant plane in the map, find an SE3 to put it as the z=0 planeSE3 MapMaker::CalcPlaneAligner(){  unsigned int nPoints = mMap.vpPoints.size();  if(nPoints < 10)    {      cout << "  MapMaker: CalcPlane: too few points to calc plane." << endl;      return SE3();    };    int nRansacs = GV2.GetInt("MapMaker.PlaneAlignerRansacs", 100, HIDDEN|SILENT);  Vector<3> v3BestMean;  Vector<3> v3BestNormal;  double dBestDistSquared = 9999999999999999.9;    for(int i=0; i<nRansacs; i++)    {      int nA = rand()%nPoints;      int nB = nA;      int nC = nA;      while(nB == nA)	nB = rand()%nPoints;      while(nC == nA || nC==nB)	nC = rand()%nPoints;            Vector<3> v3Mean = 0.33333333 * (mMap.vpPoints[nA]->v3WorldPos + 				       mMap.vpPoints[nB]->v3WorldPos + 				       mMap.vpPoints[nC]->v3WorldPos);            Vector<3> v3CA = mMap.vpPoints[nC]->v3WorldPos  - mMap.vpPoints[nA]->v3WorldPos;      Vector<3> v3BA = mMap.vpPoints[nB]->v3WorldPos  - mMap.vpPoints[nA]->v3WorldPos;      Vector<3> v3Normal = v3CA ^ v3BA;      if(v3Normal * v3Normal  == 0)	continue;      normalize(v3Normal);            double dSumError = 0.0;      for(unsigned int i=0; i<nPoints; i++)	{	  Vector<3> v3Diff = mMap.vpPoints[i]->v3WorldPos - v3Mean;	  double dDistSq = v3Diff * v3Diff;	  if(dDistSq == 0.0)	    continue;	  double dNormDist = fabs(v3Diff * v3Normal);	  	  if(dNormDist > 0.05)	    dNormDist = 0.05;	  dSumError += dNormDist;	}      if(dSumError < dBestDistSquared)	{	  dBestDistSquared = dSumError;	  v3BestMean = v3Mean;	  v3BestNormal = v3Normal;	}    }    // Done the ransacs, now collect the supposed inlier set  vector<Vector<3> > vv3Inliers;  for(unsigned int i=0; i<nPoints; i++)    {      Vector<3> v3Diff = mMap.vpPoints[i]->v3WorldPos - v3BestMean;      double dDistSq = v3Diff * v3Diff;      if(dDistSq == 0.0)	continue;      double dNormDist = fabs(v3Diff * v3BestNormal);      if(dNormDist < 0.05)	vv3Inliers.push_back(mMap.vpPoints[i]->v3WorldPos);    }    // With these inliers, calculate mean and cov  Vector<3> v3MeanOfInliers;  Zero(v3MeanOfInliers);  for(unsigned int i=0; i<vv3Inliers.size(); i++)    v3MeanOfInliers+=vv3Inliers[i];  v3MeanOfInliers *= (1.0 / vv3Inliers.size());    Matrix<3> m3Cov;  Zero(m3Cov);  for(unsigned int i=0; i<vv3Inliers.size(); i++)    {      Vector<3> v3Diff = vv3Inliers[i] - v3MeanOfInliers;      m3Cov += v3Diff.as_col() * v3Diff.as_row();    };    // Find the principal component with the minimal variance: this is the plane normal  SymEigen<3> sym(m3Cov);  Vector<3> v3Normal = sym.get_evectors()[0];    // Use the version of the normal which points towards the cam center  if(v3Normal[2] > 0)    v3Normal *= -1.0;    Matrix<3> m3Rot;  Identity(m3Rot);  m3Rot[2] = v3Normal;  m3Rot[0] = m3Rot[0] - (v3Normal * (m3Rot[0] * v3Normal));  normalize(m3Rot[0]);  m3Rot[1] = m3Rot[2] ^ m3Rot[0];    SE3 se3Aligner;  se3Aligner.get_rotation() = m3Rot;  Vector<3> v3RMean = se3Aligner * v3MeanOfInliers;  se3Aligner.get_translation() = -v3RMean;    return se3Aligner;}void MapMaker::GUICommandCallBack(void* ptr, string sCommand, string sParams){  Command c;  c.sCommand = sCommand;  c.sParams = sParams;  ((MapMaker*) ptr)->mvQueuedCommands.push_back(c);}void MapMaker::GUICommandHandler(string sCommand, string sParams)  // Called by the callback func..{  if(sCommand=="SaveMap")    {      cout << "  MapMaker: Saving the map.... " << endl;      ofstream ofs("map.dump");      for(unsigned int i=0; i<mMap.vpPoints.size(); i++)	{	  ofs << mMap.vpPoints[i]->v3WorldPos << "  ";	  ofs << mMap.vpPoints[i]->nSourceLevel << endl;	}      ofs.close();            for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)	{	  ostringstream ost1;	  ost1 << "keyframes/" << i << ".jpg";//	  img_save(mMap.vpKeyFrames[i]->aLevels[0].im, ost1.str());	  	  ostringstream ost2;	  ost2 << "keyframes/" << i << ".info";	  ofstream ofs2;	  ofs2.open(ost2.str().c_str());	  ofs2 << mMap.vpKeyFrames[i]->se3CfromW << endl;	  ofs2.close();	}      cout << "  ... done saving map." << endl;      return;    }    cout << "! MapMaker::GUICommandHandler: unhandled command "<< sCommand << endl;  exit(1);}; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -