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

📄 mapmaker.cc

📁 this is software for visual SLAM
💻 CC
📖 第 1 页 / 共 3 页
字号:
};// Rotates/translates the whole map and all keyframesvoid MapMaker::ApplyGlobalTransformationToMap(SE3 se3NewFromOld){  for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)    mMap.vpKeyFrames[i]->se3CfromW = mMap.vpKeyFrames[i]->se3CfromW * se3NewFromOld.inverse();    SO3 so3Rot = se3NewFromOld.get_rotation();  for(unsigned int i=0; i<mMap.vpPoints.size(); i++)    {      mMap.vpPoints[i]->v3WorldPos = 	se3NewFromOld * mMap.vpPoints[i]->v3WorldPos;      mMap.vpPoints[i]->RefreshPixelVectors();    }}// Applies a global scale factor to the mapvoid MapMaker::ApplyGlobalScaleToMap(double dScale){  for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)    mMap.vpKeyFrames[i]->se3CfromW.get_translation() *= dScale;    for(unsigned int i=0; i<mMap.vpPoints.size(); i++)    {      (*mMap.vpPoints[i]).v3WorldPos *= dScale;      (*mMap.vpPoints[i]).v3PixelRight_W *= dScale;      (*mMap.vpPoints[i]).v3PixelDown_W *= dScale;      (*mMap.vpPoints[i]).RefreshPixelVectors();    }}// The tracker entry point for adding a new keyframe;// the tracker thread doesn't want to hang about, so // just dumps it on the top of the mapmaker's queue to // be dealt with later, and return.void MapMaker::AddKeyFrame(KeyFrame &k){  KeyFrame *pK = new KeyFrame;  *pK = k;  mvpKeyFrameQueue.push_back(pK);  if(mbBundleRunning)   // Tell the mapmaker to stop doing low-priority stuff and concentrate on this KF first.    mbBundleAbortRequested = true;}// Mapmaker's code to handle incoming key-frames.void MapMaker::AddKeyFrameFromTopOfQueue(){  if(mvpKeyFrameQueue.size() == 0)    return;    KeyFrame *pK = mvpKeyFrameQueue[0];  mvpKeyFrameQueue.erase(mvpKeyFrameQueue.begin());  pK->MakeKeyFrame_Rest();  mMap.vpKeyFrames.push_back(pK);  // Any measurements? Update the relevant point's measurement counter status map  for(meas_it it = pK->mMeasurements.begin();      it!=pK->mMeasurements.end();      it++)    {      it->first->pMMData->sMeasurementKFs.insert(pK);      it->second.Source = Measurement::SRC_TRACKER;    }    // And maybe we missed some - this now adds to the map itself, too.  ReFindInSingleKeyFrame(*pK);    AddSomeMapPoints(3);       // .. and add more map points by epipolar search.  AddSomeMapPoints(0);  AddSomeMapPoints(1);  AddSomeMapPoints(2);    mbBundleConverged_Full = false;  mbBundleConverged_Recent = false;}// Tries to make a new map point out of a single candidate point// by searching for that point in another keyframe, and triangulating// if a match is found.bool MapMaker::AddPointEpipolar(KeyFrame &kSrc, 				KeyFrame &kTarget, 				int nLevel,				int nCandidate){  static Image<Vector<2> > imUnProj;  static bool bMadeCache = false;  if(!bMadeCache)    {      imUnProj.resize(kSrc.aLevels[0].im.size());      ImageRef ir;      do imUnProj[ir] = mCamera.UnProject(ir);      while(ir.next(imUnProj.size()));      bMadeCache = true;    }    int nLevelScale = LevelScale(nLevel);  Candidate &candidate = kSrc.aLevels[nLevel].vCandidates[nCandidate];  ImageRef irLevelPos = candidate.irLevelPos;  Vector<2> v2RootPos = LevelZeroPos(irLevelPos, nLevel);    Vector<3> v3Ray_SC = unproject(mCamera.UnProject(v2RootPos));  normalize(v3Ray_SC);  Vector<3> v3LineDirn_TC = kTarget.se3CfromW.get_rotation() * (kSrc.se3CfromW.get_rotation().inverse() * v3Ray_SC);  // Restrict epipolar search to a relatively narrow depth range  // to increase reliability  double dMean = kSrc.dSceneDepthMean;  double dSigma = kSrc.dSceneDepthSigma;  double dStartDepth = max(0.1, dMean - dSigma);  double dEndDepth = min(4.0, dMean + dSigma);    Vector<3> v3CamCenter_TC = kTarget.se3CfromW * kSrc.se3CfromW.inverse().get_translation(); // The camera end  Vector<3> v3RayStart_TC = v3CamCenter_TC + dStartDepth * v3LineDirn_TC;                               // the far-away end  Vector<3> v3RayEnd_TC = v3CamCenter_TC + dEndDepth * v3LineDirn_TC;                               // the far-away end    if(v3RayEnd_TC[2] <= v3RayStart_TC[2])  // it's highly unlikely that we'll manage to get anything out if we're facing backwards wrt the other camera's view-ray    return false;  if(v3RayEnd_TC[2] <= 0.0 )  return false;  if(v3RayStart_TC[2] <= 0.0)    v3RayStart_TC += v3LineDirn_TC * (0.001 - v3RayStart_TC[2] / v3LineDirn_TC[2]);    Vector<2> v2A = project(v3RayStart_TC);  Vector<2> v2B = project(v3RayEnd_TC);  Vector<2> v2AlongProjectedLine = v2A-v2B;    if(v2AlongProjectedLine * v2AlongProjectedLine < 0.00000001)    {      cout << "v2AlongProjectedLine too small." << endl;      return false;    }  normalize(v2AlongProjectedLine);  Vector<2> v2Normal;  v2Normal[0] = v2AlongProjectedLine[1];  v2Normal[1] = -v2AlongProjectedLine[0];    double dNormDist = v2A * v2Normal;  if(fabs(dNormDist) > mCamera.LargestRadiusInImage() )    return false;    double dMinLen = min(v2AlongProjectedLine * v2A, v2AlongProjectedLine * v2B) - 0.05;  double dMaxLen = max(v2AlongProjectedLine * v2A, v2AlongProjectedLine * v2B) + 0.05;  if(dMinLen < -2.0)  dMinLen = -2.0;  if(dMaxLen < -2.0)  dMaxLen = -2.0;  if(dMinLen > 2.0)   dMinLen = 2.0;  if(dMaxLen > 2.0)   dMaxLen = 2.0;  // Find current-frame corners which might match this  PatchFinder Finder;  Finder.MakeTemplateCoarseNoWarp(kSrc, nLevel, irLevelPos);  if(Finder.TemplateBad())  return false;    vector<Vector<2> > &vv2Corners = kTarget.aLevels[nLevel].vImplaneCorners;  vector<ImageRef> &vIR = kTarget.aLevels[nLevel].vCorners;  if(!kTarget.aLevels[nLevel].bImplaneCornersCached)    {      for(unsigned int i=0; i<vIR.size(); i++)   // over all corners in target img..	vv2Corners.push_back(imUnProj[ir(LevelZeroPos(vIR[i], nLevel))]);      kTarget.aLevels[nLevel].bImplaneCornersCached = true;    }    int nBest = -1;  int nBestZMSSD = Finder.mnMaxSSD + 1;  double dMaxDistDiff = mCamera.OnePixelDist() * (4.0 + 1.0 * nLevelScale);  double dMaxDistSq = dMaxDistDiff * dMaxDistDiff;    for(unsigned int i=0; i<vv2Corners.size(); i++)   // over all corners in target img..    {      Vector<2> v2Im = vv2Corners[i];      double dDistDiff = dNormDist - v2Im * v2Normal;      if(dDistDiff * dDistDiff > dMaxDistSq)	continue; // skip if not along epi line      if(v2Im * v2AlongProjectedLine < dMinLen)	continue; // skip if not far enough along line      if(v2Im * v2AlongProjectedLine > dMaxLen)	continue; // or too far      int nZMSSD = Finder.ZMSSDAtPoint(kTarget.aLevels[nLevel].im, vIR[i]);      if(nZMSSD < nBestZMSSD)	{	  nBest = i;	  nBestZMSSD = nZMSSD;	}    }     if(nBest == -1)   return false;   // Nothing found.    //  Found a likely candidate along epipolar ray  Finder.MakeSubPixTemplate();  Finder.SetSubPixPos(LevelZeroPos(vIR[nBest], nLevel));  bool bSubPixConverges = Finder.IterateSubPixToConvergence(kTarget,10);  if(!bSubPixConverges)    return false;    // Now triangulate the 3d point...  Vector<3> v3New;  v3New = kTarget.se3CfromW.inverse() *      ReprojectPoint(kSrc.se3CfromW * kTarget.se3CfromW.inverse(),		   mCamera.UnProject(v2RootPos), 		   mCamera.UnProject(Finder.GetSubPixPos()));    MapPoint *pNew = new MapPoint;  pNew->v3WorldPos = v3New;  pNew->pMMData = new MapMakerData();    // Patch source stuff:  pNew->pPatchSourceKF = &kSrc;  pNew->nSourceLevel = nLevel;  pNew->v3Normal_NC = (make_Vector, 0,0,-1);  pNew->irCenter = irLevelPos;  pNew->v3Center_NC = unproject(mCamera.UnProject(v2RootPos));  pNew->v3OneRightFromCenter_NC = unproject(mCamera.UnProject(v2RootPos + vec(ImageRef(nLevelScale,0))));  pNew->v3OneDownFromCenter_NC  = unproject(mCamera.UnProject(v2RootPos + vec(ImageRef(0,nLevelScale))));    normalize(pNew->v3Center_NC);  normalize(pNew->v3OneDownFromCenter_NC);  normalize(pNew->v3OneRightFromCenter_NC);    pNew->RefreshPixelVectors();      mMap.vpPoints.push_back(pNew);  mqNewQueue.push(pNew);  Measurement m;  m.Source = Measurement::SRC_ROOT;  m.v2RootPos = v2RootPos;  m.nLevel = nLevel;  m.bSubPix = true;  kSrc.mMeasurements[pNew] = m;  m.Source = Measurement::SRC_EPIPOLAR;  m.v2RootPos = Finder.GetSubPixPos();  kTarget.mMeasurements[pNew] = m;  pNew->pMMData->sMeasurementKFs.insert(&kSrc);  pNew->pMMData->sMeasurementKFs.insert(&kTarget);  return true;}double MapMaker::KeyFrameLinearDist(KeyFrame &k1, KeyFrame &k2){  Vector<3> v3KF1_CamPos = k1.se3CfromW.inverse().get_translation();  Vector<3> v3KF2_CamPos = k2.se3CfromW.inverse().get_translation();  Vector<3> v3Diff = v3KF2_CamPos - v3KF1_CamPos;  double dDist = sqrt(v3Diff * v3Diff);  return dDist;}vector<KeyFrame*> MapMaker::NClosestKeyFrames(KeyFrame &k, unsigned int N){  vector<pair<double, KeyFrame* > > vKFandScores;  for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)    {      if(mMap.vpKeyFrames[i] == &k)	continue;      double dDist = KeyFrameLinearDist(k, *mMap.vpKeyFrames[i]);      vKFandScores.push_back(make_pair(dDist, mMap.vpKeyFrames[i]));    }  if(N > vKFandScores.size())    N = vKFandScores.size();  partial_sort(vKFandScores.begin(), vKFandScores.begin() + N, vKFandScores.end());    vector<KeyFrame*> vResult;  for(unsigned int i=0; i<N; i++)    vResult.push_back(vKFandScores[i].second);  return vResult;}KeyFrame* MapMaker::ClosestKeyFrame(KeyFrame &k){  double dClosestDist = 9999999999.9;  int nClosest = -1;  for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)    {      if(mMap.vpKeyFrames[i] == &k)	continue;      double dDist = KeyFrameLinearDist(k, *mMap.vpKeyFrames[i]);      if(dDist < dClosestDist)	{	  dClosestDist = dDist;	  nClosest = i;	}    }  assert(nClosest != -1);  return mMap.vpKeyFrames[nClosest];}double MapMaker::DistToNearestKeyFrame(KeyFrame &kCurrent){  KeyFrame *pClosest = ClosestKeyFrame(kCurrent);  double dDist = KeyFrameLinearDist(kCurrent, *pClosest);  return dDist;}bool MapMaker::NeedNewKeyFrame(KeyFrame &kCurrent){  KeyFrame *pClosest = ClosestKeyFrame(kCurrent);  double dDist = KeyFrameLinearDist(kCurrent, *pClosest);  dDist *= (1.0 / kCurrent.dSceneDepthMean);    if(dDist > GV2.GetDouble("MapMaker.MaxKFDistWiggleMult",1.0,SILENT) * mdWiggleScale)    return true;  return false;}// Perform bundle adjustment on all keyframes, all map pointsvoid MapMaker::BundleAdjustAll(){  // construct the sets of kfs/points to be adjusted:  // in this case, all of them  set<KeyFrame*> sAdj;  set<KeyFrame*> sFixed;  for(unsigned int i=0; i<mMap.vpKeyFrames.size(); i++)    if(mMap.vpKeyFrames[i]->bFixed)      sFixed.insert(mMap.vpKeyFrames[i]);    else      sAdj.insert(mMap.vpKeyFrames[i]);    set<MapPoint*> sMapPoints;  for(unsigned int i=0; i<mMap.vpPoints.size();i++)    sMapPoints.insert(mMap.vpPoints[i]);    BundleAdjust(sAdj, sFixed, sMapPoints, false);}// Peform a local bundle adjustment which only adjusts// recently added key-framesvoid MapMaker::BundleAdjustRecent(){  if(mMap.vpKeyFrames.size() < 8)      { // Ignore this unless map is big enough      mbBundleConverged_Recent = true;      return;    }  // First, make a list of the keyframes we want adjusted in the adjuster.  // This will be the last keyframe inserted, and its four nearest neighbors  set<KeyFrame*> sAdjustSet;  KeyFrame *pkfNewest = mMap.vpKeyFrames.back();  sAdjustSet.insert(pkfNewest);  vector<KeyFrame*> vClosest = NClosestKeyFrames(*pkfNewest, 4);  for(int i=0; i<4; i++)    if(vClosest[i]->bFixed == false)      sAdjustSet.insert(vClosest[i]);    // Now we find the set of features which they contain.  set<MapPoint*> sMapPoints;  for(set<KeyFrame*>::iterator iter = sAdjustSet.begin();      iter!=sAdjustSet.end();      iter++)    {      map<MapPoint*,Measurement> &mKFMeas = (*iter)->mMeasurements;      for(meas_it jiter = mKFMeas.begin(); jiter!= mKFMeas.end(); jiter++)	sMapPoints.insert(jiter->first);    };    // Finally, add all keyframes which measure above points as fixed keyframes  set<KeyFrame*> sFixedSet;  for(vector<KeyFrame*>::iterator it = mMap.vpKeyFrames.begin(); it!=mMap.vpKeyFrames.end(); it++)    {      if(sAdjustSet.count(*it))	continue;      bool bInclude = false;      for(meas_it jiter = (*it)->mMeasurements.begin(); jiter!= (*it)->mMeasurements.end(); jiter++)	if(sMapPoints.count(jiter->first))	  {	    bInclude = true;	    break;	  }      if(bInclude)	sFixedSet.insert(*it);    }    BundleAdjust(sAdjustSet, sFixedSet, sMapPoints, true);}// Common bundle adjustment code. This creates a bundle-adjust instance, populates it, and runs it.void MapMaker::BundleAdjust(set<KeyFrame*> sAdjustSet, set<KeyFrame*> sFixedSet, set<MapPoint*> sMapPoints, bool bRecent){  Bundle b(mCamera);   // Our bundle adjuster  mbBundleRunning = true;  mbBundleRunningIsRecent = bRecent;    // The bundle adjuster does different accounting of keyframes and map points;  // Translation maps are stored:  map<MapPoint*, int> mPoint_BundleID;  map<int, MapPoint*> mBundleID_Point;  map<KeyFrame*, int> mView_BundleID;  map<int, KeyFrame*> mBundleID_View;    // Add the keyframes' poses to the bundle adjuster. Two parts: first nonfixed, then fixed.  for(set<KeyFrame*>::iterator it = sAdjustSet.begin(); it!= sAdjustSet.end(); it++)    {      int nBundleID = b.AddCamera((*it)->se3CfromW, (*it)->bFixed);      mView_BundleID[*it] = nBundleID;      mBundleID_View[nBundleID] = *it;    }  for(set<KeyFrame*>::iterator it = sFixedSet.begin(); it!= sFixedSet.end(); it++)    {      int nBundleID = b.AddCamera((*it)->se3CfromW, true);      mView_BundleID[*it] = nBundleID;      mBundleID_View[nBundleID] = *it;

⌨️ 快捷键说明

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