implementation of a relocalizer that tries to relocalize at the last keyframe. an interface is available for more elaborated relocalizers
This commit is contained in:
@@ -46,7 +46,8 @@ public:
|
|||||||
STAGE_PAUSED,
|
STAGE_PAUSED,
|
||||||
STAGE_FIRST_FRAME,
|
STAGE_FIRST_FRAME,
|
||||||
STAGE_SECOND_FRAME,
|
STAGE_SECOND_FRAME,
|
||||||
STAGE_DEFAULT_FRAME
|
STAGE_DEFAULT_FRAME,
|
||||||
|
STAGE_RELOCALIZING
|
||||||
};
|
};
|
||||||
enum TrackingQuality {
|
enum TrackingQuality {
|
||||||
TRACKING_INSUFFICIENT,
|
TRACKING_INSUFFICIENT,
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ public:
|
|||||||
/// Access the depth filter.
|
/// Access the depth filter.
|
||||||
DepthFilter* depthFilter() const { return depth_filter_; }
|
DepthFilter* depthFilter() const { return depth_filter_; }
|
||||||
|
|
||||||
|
/// An external place recognition module may know where to relocalize.
|
||||||
|
bool relocalizeFrameAtPose(
|
||||||
|
const int keyframe_id,
|
||||||
|
const SE3& T_kf_f,
|
||||||
|
const cv::Mat& img,
|
||||||
|
const double timestamp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit).
|
vk::AbstractCamera* cam_; //!< Camera model, can be ATAN, Pinhole or Ocam (see vikit).
|
||||||
Reprojector reprojector_; //!< Projects points from other keyframes into the current frame
|
Reprojector reprojector_; //!< Projects points from other keyframes into the current frame
|
||||||
@@ -72,6 +79,11 @@ protected:
|
|||||||
/// Processes all frames after the first two keyframes.
|
/// Processes all frames after the first two keyframes.
|
||||||
virtual UpdateResult processFrame();
|
virtual UpdateResult processFrame();
|
||||||
|
|
||||||
|
/// Try relocalizing the frame at relative position to provided keyframe.
|
||||||
|
virtual UpdateResult relocalizeFrame(
|
||||||
|
const SE3& T_cur_ref,
|
||||||
|
FramePtr ref_keyframe);
|
||||||
|
|
||||||
/// Reset the frame handler. Implement in derived class.
|
/// Reset the frame handler. Implement in derived class.
|
||||||
virtual void resetAll();
|
virtual void resetAll();
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ public:
|
|||||||
/// Return the keyframe which is furthest apart from pos.
|
/// Return the keyframe which is furthest apart from pos.
|
||||||
FramePtr getFurthestKeyframe(const Vector3d& pos) const;
|
FramePtr getFurthestKeyframe(const Vector3d& pos) const;
|
||||||
|
|
||||||
|
bool getKeyframeById(const int id, FramePtr& frame) const;
|
||||||
|
|
||||||
/// Transform the whole map with rotation R, translation t and scale s.
|
/// Transform the whole map with rotation R, translation t and scale s.
|
||||||
void transform(const Matrix3d& R, const Vector3d& t, const double& s);
|
void transform(const Matrix3d& R, const Vector3d& t, const double& s);
|
||||||
|
|
||||||
|
|||||||
@@ -129,9 +129,17 @@ int FrameHandlerBase::finishFrameProcessingCommon(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// reset if failure or requested
|
if(dropout == RESULT_FAILURE &&
|
||||||
if(dropout == RESULT_FAILURE || set_reset_)
|
(stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING ))
|
||||||
|
{
|
||||||
|
stage_ = STAGE_RELOCALIZING;
|
||||||
|
tracking_quality_ = TRACKING_INSUFFICIENT;
|
||||||
|
}
|
||||||
|
else if (dropout == RESULT_FAILURE)
|
||||||
resetAll();
|
resetAll();
|
||||||
|
if(set_reset_)
|
||||||
|
resetAll();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp)
|
|||||||
res = processSecondFrame();
|
res = processSecondFrame();
|
||||||
else if(stage_ == STAGE_FIRST_FRAME)
|
else if(stage_ == STAGE_FIRST_FRAME)
|
||||||
res = processFirstFrame();
|
res = processFirstFrame();
|
||||||
|
else if(stage_ == STAGE_RELOCALIZING)
|
||||||
|
res = relocalizeFrame(SE3(Matrix3d::Identity(), Vector3d::Zero()),
|
||||||
|
map_.getClosestKeyframe(last_frame_));
|
||||||
|
|
||||||
// set last frame
|
// set last frame
|
||||||
last_frame_ = new_frame_;
|
last_frame_ = new_frame_;
|
||||||
@@ -86,15 +89,6 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp)
|
|||||||
finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs());
|
finishFrameProcessingCommon(last_frame_->id_, res, last_frame_->nObs());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame)
|
|
||||||
{
|
|
||||||
resetAll();
|
|
||||||
last_frame_ = first_frame;
|
|
||||||
last_frame_->setKeyframe();
|
|
||||||
map_.addKeyframe(last_frame_);
|
|
||||||
stage_ = STAGE_DEFAULT_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame()
|
FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame()
|
||||||
{
|
{
|
||||||
new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero());
|
new_frame_->T_f_w_ = SE3(Matrix3d::Identity(), Vector3d::Zero());
|
||||||
@@ -155,7 +149,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
const size_t repr_n_mps = reprojector_.n_trials_;
|
const size_t repr_n_mps = reprojector_.n_trials_;
|
||||||
SVO_LOG2(repr_n_mps, repr_n_new_references);
|
SVO_LOG2(repr_n_mps, repr_n_new_references);
|
||||||
SVO_DEBUG_STREAM("Reprojection:\t nPoints = "<<repr_n_mps<<"\t \t nMatches = "<<repr_n_new_references);
|
SVO_DEBUG_STREAM("Reprojection:\t nPoints = "<<repr_n_mps<<"\t \t nMatches = "<<repr_n_new_references);
|
||||||
if(repr_n_new_references == 0) {
|
if(repr_n_new_references < 20) {
|
||||||
SVO_ERROR_STREAM("Not enough matched features.");
|
SVO_ERROR_STREAM("Not enough matched features.");
|
||||||
return RESULT_FAILURE;
|
return RESULT_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -171,7 +165,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
SVO_LOG4(sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final);
|
SVO_LOG4(sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final);
|
||||||
SVO_DEBUG_STREAM("PoseOptimizer:\t ErrInit = "<<sfba_error_init<<"px\t thresh = "<<sfba_thresh);
|
SVO_DEBUG_STREAM("PoseOptimizer:\t ErrInit = "<<sfba_error_init<<"px\t thresh = "<<sfba_thresh);
|
||||||
SVO_DEBUG_STREAM("PoseOptimizer:\t ErrFin. = "<<sfba_error_final<<"px\t nObsFin. = "<<sfba_n_edges_final);
|
SVO_DEBUG_STREAM("PoseOptimizer:\t ErrFin. = "<<sfba_error_final<<"px\t nObsFin. = "<<sfba_n_edges_final);
|
||||||
if(sfba_n_edges_final < 10)
|
if(sfba_n_edges_final < 20)
|
||||||
return RESULT_FAILURE;
|
return RESULT_FAILURE;
|
||||||
|
|
||||||
// structure optimization
|
// structure optimization
|
||||||
@@ -235,6 +229,48 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
return RESULT_IS_KEYFRAME;
|
return RESULT_IS_KEYFRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FrameHandlerMono::UpdateResult FrameHandlerMono::relocalizeFrame(
|
||||||
|
const SE3& T_cur_ref,
|
||||||
|
FramePtr ref_keyframe)
|
||||||
|
{
|
||||||
|
SVO_WARN_STREAM_THROTTLE(0.5, "Relocalizing frame");
|
||||||
|
SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(),
|
||||||
|
30, SparseImgAlign::GaussNewton, false, false);
|
||||||
|
size_t img_align_n_tracked = img_align.run(ref_keyframe, new_frame_);
|
||||||
|
if(img_align_n_tracked > 30)
|
||||||
|
{
|
||||||
|
last_frame_ = ref_keyframe;
|
||||||
|
FrameHandlerMono::UpdateResult res = processFrame();
|
||||||
|
if(res != RESULT_FAILURE)
|
||||||
|
{
|
||||||
|
stage_ = STAGE_DEFAULT_FRAME;
|
||||||
|
SVO_INFO_STREAM("Relocalization successful.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_frame_->T_f_w_ = ref_keyframe->T_f_w_;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return RESULT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FrameHandlerMono::relocalizeFrameAtPose(
|
||||||
|
const int keyframe_id,
|
||||||
|
const SE3& T_f_kf,
|
||||||
|
const cv::Mat& img,
|
||||||
|
const double timestamp)
|
||||||
|
{
|
||||||
|
FramePtr ref_keyframe;
|
||||||
|
if(!map_.getKeyframeById(keyframe_id, ref_keyframe))
|
||||||
|
return false;
|
||||||
|
new_frame_.reset(new Frame(cam_, img.clone(), timestamp));
|
||||||
|
UpdateResult res = relocalizeFrame(T_f_kf, ref_keyframe);
|
||||||
|
if(res != RESULT_FAILURE) {
|
||||||
|
last_frame_ = new_frame_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void FrameHandlerMono::resetAll()
|
void FrameHandlerMono::resetAll()
|
||||||
{
|
{
|
||||||
resetCommon();
|
resetCommon();
|
||||||
@@ -245,6 +281,15 @@ void FrameHandlerMono::resetAll()
|
|||||||
depth_filter_->reset();
|
depth_filter_->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FrameHandlerMono::setFirstFrame(const FramePtr& first_frame)
|
||||||
|
{
|
||||||
|
resetAll();
|
||||||
|
last_frame_ = first_frame;
|
||||||
|
last_frame_->setKeyframe();
|
||||||
|
map_.addKeyframe(last_frame_);
|
||||||
|
stage_ = STAGE_DEFAULT_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
bool FrameHandlerMono::needNewKf(double scene_depth_mean)
|
bool FrameHandlerMono::needNewKf(double scene_depth_mean)
|
||||||
{
|
{
|
||||||
for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it)
|
for(auto it=overlap_kfs_.begin(), ite=overlap_kfs_.end(); it!=ite; ++it)
|
||||||
|
|||||||
@@ -155,6 +155,18 @@ FramePtr Map::getFurthestKeyframe(const Vector3d& pos) const
|
|||||||
return furthest_kf;
|
return furthest_kf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Map::getKeyframeById(const int id, FramePtr& frame) const
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it)
|
||||||
|
if((*it)->id_ == id) {
|
||||||
|
found = true;
|
||||||
|
frame = *it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s)
|
void Map::transform(const Matrix3d& R, const Vector3d& t, const double& s)
|
||||||
{
|
{
|
||||||
for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it)
|
for(auto it=keyframes_.begin(), ite=keyframes_.end(); it!=ite; ++it)
|
||||||
|
|||||||
Reference in New Issue
Block a user