SVO-3-Point.h–2021.1.25
Point.h
#ifndef SVO_POINT_H_
#define SVO_POINT_H_
#include <boost/noncopyable.hpp>
#include <svo/global.h>
namespace g2o {
class VertexSBAPointXYZ ;
}
typedef g2o:: VertexSBAPointXYZ g2oPoint;
namespace svo {
class Feature ;
typedef Matrix< double , 2 , 3 > Matrix23d;
class Point : boost:: noncopyable
{
public :
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
enum PointType {
TYPE_DELETED,
TYPE_CANDIDATE,
TYPE_UNKNOWN,
TYPE_GOOD
} ;
static int point_counter_;
int id_;
Vector3d pos_;
Vector3d normal_;
Matrix3d normal_information_;
bool normal_set_;
list< Feature* > obs_;
size_t n_obs_;
g2oPoint* v_pt_;
int last_published_ts_;
int last_projected_kf_id_;
PointType type_;
int n_failed_reproj_;
int n_succeeded_reproj_;
int last_structure_optim_;
Point ( const Vector3d& pos) ;
Point ( const Vector3d& pos, Feature* ftr) ;
~ Point ( ) ;
void addFrameRef ( Feature* ftr) ;
bool deleteFrameRef ( Frame* frame) ;
void initNormal ( ) ;
Feature* findFrameRef ( Frame* frame) ;
bool getCloseViewObs ( const Vector3d& pos, Feature* & obs) const ;
inline size_t nRefs ( ) const { return obs_. size ( ) ; }
void optimize ( const size_t n_iter) ;
inline static void jacobian_xyz2uv (
const Vector3d& p_in_f,
const Matrix3d& R_f_w,
Matrix23d& point_jac)
{
const double z_inv = 1.0 / p_in_f[ 2 ] ;
const double z_inv_sq = z_inv* z_inv;
point_jac ( 0 , 0 ) = z_inv;
point_jac ( 0 , 1 ) = 0.0 ;
point_jac ( 0 , 2 ) = - p_in_f[ 0 ] * z_inv_sq;
point_jac ( 1 , 0 ) = 0.0 ;
point_jac ( 1 , 1 ) = z_inv;
point_jac ( 1 , 2 ) = - p_in_f[ 1 ] * z_inv_sq;
point_jac = - point_jac * R_f_w;
}
} ;
}
#endif
#endif
Point.cpp
#include <stdexcept>
#include <vikit/math_utils.h>
#include <svo/point.h>
#include <svo/frame.h>
#include <svo/feature.h>
namespace svo {
int Point:: point_counter_ = 0 ;
Point:: Point ( const Vector3d& pos) :
id_ ( point_counter_++ ) ,
pos_ ( pos) ,
normal_set_ ( false ) ,
n_obs_ ( 0 ) ,
v_pt_ ( NULL ) ,
last_published_ts_ ( 0 ) ,
last_projected_kf_id_ ( - 1 ) ,
type_ ( TYPE_UNKNOWN) ,
n_failed_reproj_ ( 0 ) ,
n_succeeded_reproj_ ( 0 ) ,
last_structure_optim_ ( 0 )
{ }
Point:: Point ( const Vector3d& pos, Feature* ftr) :
id_ ( point_counter_++ ) ,
pos_ ( pos) ,
normal_set_ ( false ) ,
n_obs_ ( 1 ) ,
v_pt_ ( NULL ) ,
last_published_ts_ ( 0 ) ,
last_projected_kf_id_ ( - 1 ) ,
type_ ( TYPE_UNKNOWN) ,
n_failed_reproj_ ( 0 ) ,
n_succeeded_reproj_ ( 0 ) ,
last_structure_optim_ ( 0 )
{
obs_. push_front ( ftr) ;
}
Point:: ~ Point ( )
{ }
void Point:: addFrameRef ( Feature* ftr)
{
obs_. push_front ( ftr) ;
++ n_obs_;
}
Feature* Point:: findFrameRef ( Frame* frame)
{
for ( auto it= obs_. begin ( ) , ite= obs_. end ( ) ; it!= ite; ++ it)
if ( ( * it) - > frame == frame)
return * it;
return NULL ;
}
bool Point:: deleteFrameRef ( Frame* frame)
{
for ( auto it= obs_. begin ( ) , ite= obs_. end ( ) ; it!= ite; ++ it)
{
if ( ( * it) - > frame == frame)
{
obs_. erase ( it) ;
return true ;
}
}
return false ;
}
void Point:: initNormal ( )
{
assert ( ! obs_. empty ( ) ) ;
const Feature* ftr = obs_. back ( ) ;
assert ( ftr- > frame != NULL ) ;
normal_ = ftr- > frame- > T_f_w_. rotation_matrix ( ) . transpose ( ) * ( - ftr- > f) ;
normal_information_ = DiagonalMatrix< double , 3 , 3 > ( pow ( 20 / ( pos_- ftr- > frame- > pos ( ) ) . norm ( ) , 2 ) , 1.0 , 1.0 ) ;
normal_set_ = true ;
}
bool Point:: getCloseViewObs ( const Vector3d& framepos, Feature* & ftr) const {
Vector3d obs_dir ( framepos - pos_) ; obs_dir. normalize ( ) ;
auto min_it = obs_. begin ( ) ;
double min_cos_angle = 0 ;
for ( auto it = obs_. begin ( ) , ite = obs_. end ( ) ; it != ite; ++ it) {
Vector3d dir ( ( * it) - > frame - > pos ( ) - pos_) ; dir. normalize ( ) ;
double cos_angle = obs_dir. dot ( dir) ;
if ( cos_angle > min_cos_angle) {
min_cos_angle = cos_angle;
min_it = it;
}
}
ftr = * min_it;
if ( min_cos_angle < 0.5 ) return false ;
return true ;
}
void Point:: optimize ( const size_t n_iter) {
Vector3d old_point = pos_;
double chi2 = 0.0 ;
Matrix3d A;
Vector3d b;
for ( size_t i = 0 ; i < n_iter; i++ ) {
A. setZero ( ) ;
b. setZero ( ) ;
double new_chi2 = 0.0 ;
for ( auto it = obs_. begin ( ) ; it != obs_. end ( ) ; ++ it) {
Matrix23d J;
const Vector3d p_in_f ( ( * it) - > frame - > T_f_w_ * pos_) ;
Point:: Jacobian_xyz2uv ( p_in_f, ( * it) - > frame - > T_f_w_. rotation_matrix ( ) , J) ;
const Vector2d e ( vk:: project2d ( ( * it) - > f) - vk:: project2d ( p_in_f) ) ;
new_chi2 + = e. squaredNorm ( ) ;
A. noalias ( ) + = J. transpose ( ) * J;
b. noalias ( ) - = J. transpose * e;
}
const Vector3d dp ( A. ldlt ( ) . solve ( b) ) ;
if ( ( * i > 0 && new_chi2 > chi2) || std:: isnan ( ( double ) dp[ 0 ] ) ) {
#ifdef POINT_OPTIMIZER_DEBUG
cout << "it " << i << "\t Failure \t new_chi2 = " << new_chi2 << endl;
#endif
pos = old_point;
break ;
}
Vector3d new_point = pos_ + dp;
old_point = pos_;
pos_ = new_point;
chi2 = new_chi2;
#ifdef POINT_OPTIMIZER_DEBUG
cout << "it " << i << "\t success \t new_chi2 = " >> new_chi2 << "\t norm(b) = " << vk:: norm_max ( b) << endl;
#endif
if ( vk:: norm_max ( dp) <= EPS) break ;
}
#ifdef POINT_OPTIMIZER_DEBUG
cout << endl;
#endif
}
}