change feature score in fast algorithm and add brightness

This commit is contained in:
gfuse
2021-09-16 19:12:24 +02:00
parent 887487b4fc
commit 1e685aa829
14 changed files with 3586 additions and 10380 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -104,7 +104,7 @@ public:
std::shared_ptr<Frame> frame, std::shared_ptr<Frame> frame,
const ImgPyr& img_pyr, const ImgPyr& img_pyr,
const double detection_threshold, const double detection_threshold,
Features& fts, list<shared_ptr<Feature>>& fts,
cv::Mat* descriptors= nullptr); cv::Mat* descriptors= nullptr);
opencl* gpu_fast_; opencl* gpu_fast_;
}; };
+3 -3
View File
@@ -132,12 +132,12 @@ public:
std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> UpdateSvo(double x/*in camera frame*/,double z/*in camera frame*/,double pitch/*in camera frame*/) { std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> UpdateSvo(double x/*in camera frame*/,double z/*in camera frame*/,double pitch/*in camera frame*/) {
while(lock)usleep(5); while(lock)usleep(5);
lock=true; lock=true;
filter_->correct(x,-1.0*z,pitch); filter_->correct(10.0*x,-1.0*z,-1.0*pitch);
lock=false; lock=false;
return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(filter_->state_(0),-1.0*filter_->state_(1),(filter_->state_(2)))); return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(0.1*filter_->state_(0),-1.0*filter_->state_(1),-1.0*(filter_->state_(2))));
}; };
std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> get_location(){ std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> get_location(){
return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(filter_->state_(0),-1.0*filter_->state_(1),(filter_->state_(2)))); return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(0.1*filter_->state_(0),-1.0*filter_->state_(1),-1.0*(filter_->state_(2))));
} }
bool start_=false; bool start_=false;
private: private:
+1 -1
View File
@@ -1,6 +1,6 @@
<launch> <launch>
<node pkg="vio" type="vio" name="vio" clear_params="true" output="screen" /> <!-- node pkg="vio" type="vio" name="vio" clear_params="true" output="screen" / -->
<!-- Camera topic to subscribe to --> <!-- Camera topic to subscribe to -->
<param name="vio/cam_topic" value="/CoreNode/grey_img" type="str" /> <param name="vio/cam_topic" value="/CoreNode/grey_img" type="str" />
Binary file not shown.
+5 -4
View File
@@ -10,7 +10,8 @@ svo:
kfselect_mindist: 0.01 kfselect_mindist: 0.01
poseoptim_thresh: 8.0 poseoptim_thresh: 8.0
init_min_inliers: 30 init_min_inliers: 30
ACC_noise: 100 #acc white noise in continuous in EKF map_scale: 0.5
GYO_noise: 100 #gyro white noise in continuous in EKF ACC_noise: 2000 #acc white noise in continuous in EKF
svo_ekf: 0.05 #Svo noise that will be devided by number of Reprojected points after opmization in EKF GYO_noise: 2000 #gyro white noise in continuous in EKF
Cmd_Cov: 100 #control vector noise in EKF svo_ekf: 0.0001 #Svo noise that will be devided by number of Reprojected points after opmization in EKF
Cmd_Cov: 2000 #control vector noise in EKF
+1 -1
View File
@@ -269,7 +269,7 @@ namespace vio {
#if VIO_DEBUG #if VIO_DEBUG
fprintf(log_,"[%s] If point is visible? %f, %f, %f\n",vio::time_in_HH_MM_SS_MMM().c_str(),xyz_f.x(),xyz_f.y(),xyz_f.z()); fprintf(log_,"[%s] If point is visible? %f, %f, %f\n",vio::time_in_HH_MM_SS_MMM().c_str(),xyz_f.x(),xyz_f.y(),xyz_f.z());
#endif #endif
if(xyz_f.z() > 0.0) { if(xyz_f.z() < 0.0) {
++it; // behind the camera ++it; // behind the camera
continue; continue;
} }
+18 -18
View File
@@ -69,51 +69,51 @@ void FastDetector::detect(
std::shared_ptr<Frame> frame, std::shared_ptr<Frame> frame,
const ImgPyr& img_pyr, const ImgPyr& img_pyr,
const double detection_threshold, const double detection_threshold,
Features& fts, list<shared_ptr<Feature>>& fts,
cv::Mat* descriptors){ cv::Mat* descriptors){
Corners corners(grid_n_cols_*grid_n_rows_, Corner(0,0,detection_threshold,0,0.0f)); Corners corners(grid_n_cols_*grid_n_rows_, Corner(0,0,0.0,0,0.0f));
std::vector<cv::KeyPoint> keypoints; std::vector<cv::KeyPoint> keypoints;
fts.clear();
for(int L=0; L<n_pyr_levels_; ++L) for(int L=0; L<n_pyr_levels_; ++L)
{ {
const int scale = (1<<L); const int scale = (1<<L);
cv::Mat img=img_pyr.at(L); cv::Mat img=img_pyr.at(L);
if(!gpu_fast_->reload_buf(0,0,img)){ if(!gpu_fast_->reload_buf(0,0,img)){
std::cerr<<"Failed to write into GPU goodbye :)"<<'\n'; ROS_ERROR("Failed to write into GPU goodbye :)");
exit(0); exit(0);
}; };
cl_int icorner[1]={0}; cl_int icorner[1]={0};
if(!gpu_fast_->reload_buf(0,2,icorner)){ if(!gpu_fast_->reload_buf(0,2,icorner)){
std::cerr<<"Failed to write into GPU goodbye :)"<<'\n'; ROS_ERROR("Failed to write into GPU goodbye :)");
exit(0); exit(0);
}; };
gpu_fast_->run(0,img.cols,img.rows); gpu_fast_->run(0,img.cols,img.rows);
int count[1]={0}; cl_int count[1]={0};
gpu_fast_->read(0,2,1,count); gpu_fast_->read(0,2,1,count);
cl_int2 fast_corners[350000]={0}; cl_int2 fast_corners[350000]={0};
gpu_fast_->read(0,1,count[0],fast_corners); gpu_fast_->read(0,1,count[0],fast_corners);
if(count[0]<1 ){
ROS_ERROR("Can not communicate with GPU");
exit(0);
}
for(uint i=0;i<count[0];++i) for(uint i=0;i<count[0];++i)
{ {
if(fast_corners[i].x<0 || fast_corners[i].x>img_pyr[L].cols || fast_corners[i].y>img_pyr[L].rows || fast_corners[i].y<0) if(fast_corners[i].x<0 || fast_corners[i].x>img_pyr[L].cols || fast_corners[i].y>img_pyr[L].rows || fast_corners[i].y<0){
continue; continue;
}
const int k = static_cast<int>((fast_corners[i].y*scale)/cell_size_)*grid_n_cols_ const int k = static_cast<int>((fast_corners[i].y*scale)/cell_size_)*grid_n_cols_
+ static_cast<int>((fast_corners[i].x*scale)/cell_size_); + static_cast<int>((fast_corners[i].x*scale)/cell_size_);
if(grid_occupancy_[k] || k > corners.size()) if(grid_occupancy_[k] || k > corners.size()){
continue; continue;
}
const float score = vk::shiTomasiScore(img_pyr[L], fast_corners[i].x, fast_corners[i].y); const float score = vk::shiTomasiScore(img_pyr[L], fast_corners[i].x, fast_corners[i].y);
if(score > corners.at(k).score){ if(score > corners.at(k).score){
corners.at(k) = Corner(fast_corners[i].x, fast_corners[i].y, score, L, 0.0f); corners.at(k) = Corner(fast_corners[i].x*scale, fast_corners[i].y*scale, score, L, 0.0f);
// Create feature for every corner that has high enough corner score fts.push_back(make_shared<Feature>(frame, Vector2d(corners.at(k).x, corners.at(k).y)*scale, corners.at(k).level));
if(corners.at(k).score > detection_threshold){ if(descriptors)keypoints.push_back(cv::KeyPoint(fast_corners[i].x*scale, fast_corners[i].y*scale, 1));
fts.push_back(make_shared<Feature>(frame, Vector2d(corners.at(k).x, corners.at(k).y)*scale, corners.at(k).level));
if(descriptors)keypoints.push_back(cv::KeyPoint(fast_corners[i].x*scale, fast_corners[i].y*scale, 1));
}
} }
} }
} }
if(descriptors){ if(descriptors){
cv::Ptr<cv::xfeatures2d::FREAK> extractor = cv::xfeatures2d::FREAK::create(true, true, 22.0f, 4); cv::Ptr<cv::xfeatures2d::FREAK> extractor = cv::xfeatures2d::FREAK::create(true, true, 22.0f, 4);
+6 -4
View File
@@ -131,8 +131,9 @@ void FrameHandlerMono::addImage(const cv::Mat& img, const double timestamp,const
FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame() FrameHandlerMono::UpdateResult FrameHandlerMono::processFirstFrame()
{ {
ukfPtr_.start_=true; ukfPtr_.start_=true;
if(klt_homography_init_->addFirstFrame(new_frame_) == initialization::FAILURE) if(klt_homography_init_->addFirstFrame(new_frame_) == initialization::FAILURE){
return RESULT_NO_KEYFRAME; return RESULT_NO_KEYFRAME;
}
new_frame_->setKeyframe(); new_frame_->setKeyframe();
map_.reset(); map_.reset();
map_.addKeyframe(new_frame_); map_.addKeyframe(new_frame_);
@@ -224,7 +225,8 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
fabs(new_frame_->T_f_w_.pitch()-last_frame_->T_f_w_.pitch())); fabs(new_frame_->T_f_w_.pitch()-last_frame_->T_f_w_.pitch()));
#endif #endif
if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>0.5 || if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>0.5 ||
fabs(new_frame_->T_f_w_.pitch()-last_frame_->T_f_w_.pitch())>M_PI_2){ fabs(new_frame_->T_f_w_.pitch()-last_frame_->T_f_w_.pitch())>M_PI_2 ||
sfba_n_edges_final < Config::qualityMinFts()/*10*/){
auto init_f= ukfPtr_.get_location(); auto init_f= ukfPtr_.get_location();
new_frame_->T_f_w_=init_f.second; new_frame_->T_f_w_=init_f.second;
new_frame_->Cov_ = init_f.first; new_frame_->Cov_ = init_f.first;
@@ -242,7 +244,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
#endif #endif
optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter()); optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter());
depth_filter_->addFrame(new_frame_); depth_filter_->addFrame(new_frame_);
if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()/*10*/){ if(sfba_n_edges_final < Config::qualityMinFts()){
return RESULT_FAILURE; return RESULT_FAILURE;
} }
+12
View File
@@ -28,9 +28,12 @@ namespace initialization {
InitResult KltHomographyInit::addFirstFrame(FramePtr frame_ref) InitResult KltHomographyInit::addFirstFrame(FramePtr frame_ref)
{ {
reset(); reset();
features_ref_.clear();
px_ref_.clear();
detectFeatures(frame_ref, px_ref_, features_ref_, gpu_fast_); detectFeatures(frame_ref, px_ref_, features_ref_, gpu_fast_);
if(px_ref_.size() < 100) if(px_ref_.size() < 100)
{ {
ROS_WARN("Process first frame. Detected observations are px=%d, features=%d less than 100",px_ref_.size(),features_ref_.size());
return FAILURE; return FAILURE;
} }
#if VIO_DEBUG #if VIO_DEBUG
@@ -80,6 +83,15 @@ InitResult KltHomographyInit::addSecondFrame(FramePtr frame_cur)
return NO_KEYFRAME; return NO_KEYFRAME;
} }
frame_cur->T_f_w_ = T_cur_from_ref_; frame_cur->T_f_w_ = T_cur_from_ref_;
// Rescale the map such that the mean scene depth is equal to the specified scale
vector<double> depth_vec;
for(size_t i=0; i<xyz_in_cur_.size(); ++i)
depth_vec.push_back((xyz_in_cur_[i]).z());
double scene_depth_median = vk::getMedian(depth_vec);
double scale = Config::mapScale()/scene_depth_median;
frame_cur->T_f_w_ = SE2_5(T_cur_from_ref_.se2() * frame_ref_->T_f_w_.se2());
frame_cur->T_f_w_ = SE2_5(SE2(frame_cur->T_f_w_.se2().rotation_matrix(),
-frame_cur->T_f_w_.se2().rotation_matrix()*(frame_ref_->pos() + scale*(frame_cur->pos() - frame_ref_->pos()))));
// For each inlier create 3D point and add feature in both frames // For each inlier create 3D point and add feature in both frames
for(auto&& id:inliers_){ for(auto&& id:inliers_){
Features::iterator first=features_ref_.begin(); Features::iterator first=features_ref_.begin();
+2 -10
View File
@@ -102,10 +102,7 @@ void optimizeGaussNewton(
// check if error increased // check if error increased
if((iter > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dT[0])) if((iter > 0 && new_chi2 > chi2) || (bool) std::isnan((double)dT[0]))
{ {
//#if VIO_DEBUG
// fprintf(log,"[%s] it:%d \t FAILURE \t new_chi2: %f\n",
// vio::time_in_HH_MM_SS_MMM().c_str(),iter,new_chi2);
//#endif
frame->T_f_w_ = T_old; // roll-back frame->T_f_w_ = T_old; // roll-back
break; break;
} }
@@ -113,12 +110,7 @@ void optimizeGaussNewton(
// update the model // update the model
T_old = frame->T_f_w_; T_old = frame->T_f_w_;
frame->T_f_w_=SE2_5(T_old.se2().translation().x()+dT.x(),T_old.se2().translation().y()+dT.y(),T_old.pitch()+dT.z()); frame->T_f_w_=SE2_5(T_old.se2().translation().x()+dT.x(),T_old.se2().translation().y()+dT.y(),T_old.pitch()+dT.z());
chi2 = new_chi2; chi2 = new_chi2;
//#if VIO_DEBUG
// fprintf(log,"[%s] it:%d \t Success \t new_chi2: %f \t dT = %f, %f, %f\n",
// vio::time_in_HH_MM_SS_MMM().c_str(),iter,new_chi2,dT.x(),dT.y(),dT.z());
//#endif
// stop when converged // stop when converged
if(vk::norm_max(dT) <= EPS) if(vk::norm_max(dT) <= EPS)
@@ -148,7 +140,7 @@ void optimizeGaussNewton(
error_init /=chi2_vec_init.size(); error_init /=chi2_vec_init.size();
if(!chi2_vec_final.empty())for(auto&& i:chi2_vec_final)error_final+=i; if(!chi2_vec_final.empty())for(auto&& i:chi2_vec_final)error_final+=i;
error_final /= chi2_vec_final.size(); error_final /= chi2_vec_final.size();
fprintf(log,"[%s] n deleted obs = %d \t n obs felt =%d \t error init =%f \t error end=%f\n", fprintf(log,"[%s] n deleted obs = %d \t n obs with reprojection error less than 0.5 px =%d \t error init =%f \t error end=%f\n",
vio::time_in_HH_MM_SS_MMM().c_str(),n_deleted_refs,num_obs,error_init,error_final); vio::time_in_HH_MM_SS_MMM().c_str(),n_deleted_refs,num_obs,error_init,error_final);
#endif #endif
} }
+2
View File
@@ -112,6 +112,7 @@ namespace vio {
const int k = static_cast<int>((*point)->px.y() / grid_.cell_size) * const int k = static_cast<int>((*point)->px.y() / grid_.cell_size) *
grid_.grid_n_cols grid_.grid_n_cols
+ static_cast<int>((*point)->px.x() / grid_.cell_size); + static_cast<int>((*point)->px.x() / grid_.cell_size);
if(k>grid_.cells.size()-1)continue;
assert(grid_.cells.at(k) != nullptr); assert(grid_.cells.at(k) != nullptr);
Vector2d px((int) (*point)->px.x(), Vector2d px((int) (*point)->px.x(),
(int) (*point)->px.y()); (int) (*point)->px.y());
@@ -129,6 +130,7 @@ namespace vio {
const int k = static_cast<int>((*point)->px.y()/ grid_.cell_size) * const int k = static_cast<int>((*point)->px.y()/ grid_.cell_size) *
grid_.grid_n_cols grid_.grid_n_cols
+ static_cast<int>((*point)->px.x() / grid_.cell_size); + static_cast<int>((*point)->px.x() / grid_.cell_size);
if(k>grid_.cells.size()-1)continue;
assert(grid_.cells.at(k) != nullptr); assert(grid_.cells.at(k) != nullptr);
Vector2d px((int) (*point)->px.x(), Vector2d px((int) (*point)->px.x(),
(int) (*point)->px.y()); (int) (*point)->px.y());
+16 -6
View File
@@ -119,12 +119,22 @@ void VioNode::imgCb(const sensor_msgs::ImageConstPtr& msg)
try { try {
cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image; cv::Mat img=cv_bridge::toCvShare(msg, "mono8")->image;
if(img.empty())return; if(img.empty())return;
cv::Mat imgbul;//tem; cv::Mat imgbul,float_img,frame,show;//tem;
cv::Laplacian(img,imgbul,CV_64F); img.convertTo(float_img,CV_64F,1.f/255);
float_img*=2.0;
float_img+=0.2;
float_img.convertTo(frame,CV_8UC1,255);
cv::Laplacian(frame,imgbul,CV_64F);
cv::Scalar mean, stddev; cv::Scalar mean, stddev;
meanStdDev(imgbul, mean, stddev, cv::Mat()); meanStdDev(imgbul, mean, stddev, cv::Mat());
if(stddev.val[0] * stddev.val[0]< 50.0)return; cv::cvtColor(frame,show,CV_GRAY2RGB);
vo_->addImage(img, msg->header.stamp.toSec(),msg->header.stamp); imshow("New Image", show);
cv::waitKey(10);
if(stddev.val[0] * stddev.val[0]< 30.0){
ROS_WARN("Frame is blur or too dark");
return;
}
vo_->addImage(frame, msg->header.stamp.toSec(),msg->header.stamp);
} catch (cv_bridge::Exception& e) { } catch (cv_bridge::Exception& e) {
ROS_ERROR("vo exception: %s", e.what()); ROS_ERROR("vo exception: %s", e.what());
} }
@@ -152,7 +162,7 @@ void VioNode::imuCb(const sensor_msgs::ImuPtr &imu) {
auto odom=vo_->ukfPtr_.get_location(); auto odom=vo_->ukfPtr_.get_location();
fprintf(vo_->log_,"[%s] Odometry x=%f, y=%f, theta=%f\n",vio::time_in_HH_MM_SS_MMM().c_str(), fprintf(vo_->log_,"[%s] Odometry x=%f, y=%f, theta=%f\n",vio::time_in_HH_MM_SS_MMM().c_str(),
odom.second.se2().translation()(0),odom.second.se2().translation()(1), odom.second.se2().translation()(0),odom.second.se2().translation()(1),
-odom.second.pitch()); odom.second.pitch());
visualizer_.publishMinimal(vo_->ukfPtr_, imu->header.stamp.toSec()); visualizer_.publishMinimal(vo_->ukfPtr_, imu->header.stamp.toSec());
#endif #endif
} }
@@ -170,7 +180,7 @@ void VioNode::imu_th(){
while(start_ && !boost::this_thread::interruption_requested()) while(start_ && !boost::this_thread::interruption_requested())
{ {
Q.callOne(ros::WallDuration(10,0.0)); Q.callOne(ros::WallDuration(10,0.0));
usleep(20000); usleep(10000);
} }
} }