ORBSLAM2
代码
bool Tracking:: TrackWithMotionModel ( )
{
ORBmatcher matcher ( 0.9 , true ) ;
UpdateLastFrame ( ) ;
mCurrentFrame. SetPose ( mVelocity* mLastFrame. mTcw) ;
fill ( mCurrentFrame. mvpMapPoints. begin ( ) , mCurrentFrame. mvpMapPoints. end ( ) , static_cast < MapPoint* > ( NULL ) ) ;
int th;
if ( mSensor!= System:: STEREO)
th= 15 ;
else
th= 7 ;
int nmatches = matcher. SearchByProjection ( mCurrentFrame, mLastFrame, th, mSensor== System:: MONOCULAR) ;
if ( nmatches< 20 )
{
fill ( mCurrentFrame. mvpMapPoints. begin ( ) , mCurrentFrame. mvpMapPoints. end ( ) , static_cast < MapPoint* > ( NULL ) ) ;
nmatches = matcher. SearchByProjection ( mCurrentFrame, mLastFrame, 2 * th, mSensor== System:: MONOCULAR) ;
}
if ( nmatches< 20 )
return false ;
Optimizer:: PoseOptimization ( & mCurrentFrame) ;
int nmatchesMap = 0 ;
for ( int i = 0 ; i< mCurrentFrame. N; i++ )
{
if ( mCurrentFrame. mvpMapPoints[ i] )
{
if ( mCurrentFrame. mvbOutlier[ i] )
{
MapPoint* pMP = mCurrentFrame. mvpMapPoints[ i] ;
mCurrentFrame. mvpMapPoints[ i] = static_cast < MapPoint* > ( NULL ) ;
mCurrentFrame. mvbOutlier[ i] = false ;
pMP- > mbTrackInView = false ;
pMP- > mnLastFrameSeen = mCurrentFrame. mnId;
nmatches-- ;
}
else if ( mCurrentFrame. mvpMapPoints[ i] - > Observations ( ) > 0 )
nmatchesMap++ ;
}
}
if ( mbOnlyTracking)
{
mbVO = nmatchesMap< 10 ;
return nmatches> 20 ;
}
return nmatchesMap>= 10 ;
}
int ORBmatcher:: SearchByProjection ( Frame & CurrentFrame, const Frame & LastFrame, const float th, const bool bMono)
{
int nmatches = 0 ;
vector< int > rotHist[ HISTO_LENGTH] ;
for ( int i= 0 ; i< HISTO_LENGTH; i++ )
rotHist[ i] . reserve ( 500 ) ;
const float factor = 1.0f / HISTO_LENGTH;
const cv:: Mat Rcw = CurrentFrame. mTcw. rowRange ( 0 , 3 ) . colRange ( 0 , 3 ) ;
const cv:: Mat tcw = CurrentFrame. mTcw. rowRange ( 0 , 3 ) . col ( 3 ) ;
const cv:: Mat twc = - Rcw. t ( ) * tcw;
const cv:: Mat Rlw = LastFrame. mTcw. rowRange ( 0 , 3 ) . colRange ( 0 , 3 ) ;
const cv:: Mat tlw = LastFrame. mTcw. rowRange ( 0 , 3 ) . col ( 3 ) ;
const cv:: Mat tlc = Rlw* twc+ tlw;
const bool bForward = tlc. at< float > ( 2 ) > CurrentFrame. mb && ! bMono;
const bool bBackward = - tlc. at< float > ( 2 ) > CurrentFrame. mb && ! bMono;
for ( int i= 0 ; i< LastFrame. N; i++ )
{
MapPoint* pMP = LastFrame. mvpMapPoints[ i] ;
if ( pMP)
{
if ( ! LastFrame. mvbOutlier[ i] )
{
cv:: Mat x3Dw = pMP- > GetWorldPos ( ) ;
cv:: Mat x3Dc = Rcw* x3Dw+ tcw;
const float xc = x3Dc. at< float > ( 0 ) ;
const float yc = x3Dc. at< float > ( 1 ) ;
const float invzc = 1.0 / x3Dc. at< float > ( 2 ) ;
if ( invzc< 0 )
continue ;
float u = CurrentFrame. fx* xc* invzc+ CurrentFrame. cx;
float v = CurrentFrame. fy* yc* invzc+ CurrentFrame. cy;
if ( u< CurrentFrame. mnMinX || u> CurrentFrame. mnMaxX)
continue ;
if ( v< CurrentFrame. mnMinY || v> CurrentFrame. mnMaxY)
continue ;
int nLastOctave = LastFrame. mvKeys[ i] . octave;
float radius = th* CurrentFrame. mvScaleFactors[ nLastOctave] ;
vector< size_t> vIndices2;
if ( bForward)
vIndices2 = CurrentFrame. GetFeaturesInArea ( u, v, radius, nLastOctave) ;
else if ( bBackward)
vIndices2 = CurrentFrame. GetFeaturesInArea ( u, v, radius, 0 , nLastOctave) ;
else
vIndices2 = CurrentFrame. GetFeaturesInArea ( u, v, radius, nLastOctave- 1 , nLastOctave+ 1 ) ;
if ( vIndices2. empty ( ) )
continue ;
const cv:: Mat dMP = pMP- > GetDescriptor ( ) ;
int bestDist = 256 ;
int bestIdx2 = - 1 ;
for ( vector< size_t> :: const_iterator vit= vIndices2. begin ( ) , vend= vIndices2. end ( ) ; vit!= vend; vit++ )
{
const size_t i2 = * vit;
if ( CurrentFrame. mvpMapPoints[ i2] )
if ( CurrentFrame. mvpMapPoints[ i2] - > Observations ( ) > 0 )
continue ;
if ( CurrentFrame. mvuRight[ i2] > 0 )
{
const float ur = u - CurrentFrame. mbf* invzc;
const float er = fabs ( ur - CurrentFrame. mvuRight[ i2] ) ;
if ( er> radius)
continue ;
}
const cv:: Mat & d = CurrentFrame. mDescriptors. row ( i2) ;
const int dist = DescriptorDistance ( dMP, d) ;
if ( dist< bestDist)
{
bestDist= dist;
bestIdx2= i2;
}
}
if ( bestDist<= TH_HIGH)
{
CurrentFrame. mvpMapPoints[ bestIdx2] = pMP;
nmatches++ ;
if ( mbCheckOrientation)
{
float rot = LastFrame. mvKeysUn[ i] . angle- CurrentFrame. mvKeysUn[ bestIdx2] . angle;
if ( rot< 0.0 )
rot+ = 360.0f ;
int bin = round ( rot* factor) ;
if ( bin== HISTO_LENGTH)
bin= 0 ;
assert ( bin>= 0 && bin< HISTO_LENGTH) ;
rotHist[ bin] . push_back ( bestIdx2) ;
}
}
}
}
}
if ( mbCheckOrientation)
{
int ind1= - 1 ;
int ind2= - 1 ;
int ind3= - 1 ;
ComputeThreeMaxima ( rotHist, HISTO_LENGTH, ind1, ind2, ind3) ;
for ( int i= 0 ; i< HISTO_LENGTH; i++ )
{
if ( i!= ind1 && i!= ind2 && i!= ind3)
{
for ( size_t j= 0 , jend= rotHist[ i] . size ( ) ; j< jend; j++ )
{
CurrentFrame. mvpMapPoints[ rotHist[ i] [ j] ] = static_cast < MapPoint* > ( NULL ) ;
nmatches-- ;
}
}
}
}
return nmatches;
}