ch13问题

1.setMeasurement()

决定了边类中computeError()函数和linearizeOplus()函数中的_measurement的值

2.g2o_types.h

外参*T

3.留意相机内参什么时候传入

backend.cpp中传了外参

if (feat->is_on_left_iamge_)
{
    //这里传入了一个外参
    edge = new EdgeProjection(K,left_ext);
}
else
{
    edge = new EdgeProjection(K,right_ext);
}

内参还不知道

4.new 类和new 类()区别

有小括号时,小括号中可以有若干参数,也可以没有参数。
比如
ptest = new test(); 这样在构造时就会调用无参构造test();
ptest = new test(1); 就会调用构造函数test(int),即一个整型参数的构造函数。
2 没有小括号时,默认调用无参构造。

ptest = new test;
和ptest = new test();是一样的。

5.setLevel()

优化完成后,对每一条边都进行检查,剔除误差较大的边(认为是错误的边),并设置setLevel为0(这里应该是原作者写错了,感觉应该是1),即下次不再对该边进行优化

e->setLevel(1);// 不优化

这里每个边都有一个level的概念,默认情况下,g2o只处理level=0的边,在orbslam中,如果确定某个边的重投影误差过大,则把level设置为1,也就是舍弃这个边对于整个优化的影响)

参考:
SLAM-G2O分析
g2o学习笔记

6.外点为什么还计算误差

frontend.cpp
if (features[i]->is_outlier_)
{
e->computeError();
}

7.weak_ptr expired() reset()

feat->map_point_.reset();
将指针置空,据本人理解,释放指针

expired 用于检测所管理的对象是否已经释放, 如果已经释放, 返回 true; 否则返回 false.

// weak_ptr::reset example
#include <iostream>
#include <memory>

int main () {
  std::shared_ptr<int> sp (new int(10));

  std::weak_ptr<int> wp(sp);

  std::cout << "1. wp " << (wp.expired()?"is":"is not") << " expired\n";

  wp.reset();

  std::cout << "2. wp " << (wp.expired()?"is":"is not") << " expired\n";

  return 0;
}

结果:

1. wp is not expired
2. wp is expired

代码出处:
std::weak_ptr::reset

8.g2o::SparseOptimizer::optimize()里面做了什么 optimizer.optimize(10);

在这里插入图片描述
参考:G2O使用要点总结

/**
     * starts one optimization run given the current configuration of the graph, 
     * and the current settings stored in the class instance.
     * It can be called only after initializeOptimization
     */
    int optimize(int iterations, bool online = false);
int SparseOptimizer::optimize(int iterations, bool online)
  {
    if (_ivMap.size() == 0) {
      cerr << __PRETTY_FUNCTION__ << ": 0 vertices to optimize, maybe forgot to call initializeOptimization()" << endl;
      return -1;
    }

    int cjIterations=0;
    number_t cumTime=0;
    bool ok=true;

    ok = _algorithm->init(online);
    if (! ok) {
      cerr << __PRETTY_FUNCTION__ << " Error while initializing" << endl;
      return -1;
    }

    _batchStatistics.clear();
    if (_computeBatchStatistics)
      _batchStatistics.resize(iterations);
    
    OptimizationAlgorithm::SolverResult result = OptimizationAlgorithm::OK;
    for (int i=0; i<iterations && ! terminate() && ok; i++){
      preIteration(i);

      if (_computeBatchStatistics) {
        G2OBatchStatistics& cstat = _batchStatistics[i];
        G2OBatchStatistics::setGlobalStats(&cstat);
        cstat.iteration = i;
        cstat.numEdges =  _activeEdges.size();
        cstat.numVertices = _activeVertices.size();
      }
      
      number_t ts = get_monotonic_time();
      result = _algorithm->solve(i, online);
      ok = ( result == OptimizationAlgorithm::OK );

      bool errorComputed = false;
      if (_computeBatchStatistics) {
        computeActiveErrors();
        errorComputed = true;
        _batchStatistics[i].chi2 = activeRobustChi2();
        _batchStatistics[i].timeIteration = get_monotonic_time()-ts;
      }

      if (verbose()){
        number_t dts = get_monotonic_time()-ts;
        cumTime += dts;
        if (! errorComputed)
          computeActiveErrors();
        cerr << "iteration= " << i
          << "\t chi2= " << FIXED(activeRobustChi2())
          << "\t time= " << dts
          << "\t cumTime= " << cumTime
          << "\t edges= " << _activeEdges.size();
        _algorithm->printVerbose(cerr);
        cerr << endl;
      }
      ++cjIterations; 
      postIteration(i);
    }
    if (result == OptimizationAlgorithm::Fail) {
      return 0;
    }
    return cjIterations;
  }

computeActiveErrors:

void SparseOptimizer::computeActiveErrors()
  {
    // call the callbacks in case there is something registered
    HyperGraphActionSet& actions = _graphActions[AT_COMPUTEACTIVERROR];
    if (actions.size() > 0) {
      for (HyperGraphActionSet::iterator it = actions.begin(); it != actions.end(); ++it)
        (*(*it))(this);
    }

#   ifdef G2O_OPENMP
#   pragma omp parallel for default (shared) if (_activeEdges.size() > 50)
#   endif
    for (int k = 0; k < static_cast<int>(_activeEdges.size()); ++k) {
      OptimizableGraph::Edge* e = _activeEdges[k];
      e->computeError();
    }

#  ifndef NDEBUG
    for (int k = 0; k < static_cast<int>(_activeEdges.size()); ++k) {
      OptimizableGraph::Edge* e = _activeEdges[k];
      bool hasNan = arrayHasNaN(e->errorData(), e->dimension());
      if (hasNan) {
        cerr << "computeActiveErrors(): found NaN in error for edge " << e << endl;
      }
    }
#  endif

  }

9.frontend.cpp:int Frontend::TrackLastFrame()

else
{
    /********************kps_last与kps_current这不就一样了么**********************/
    kps_last.push_back(kp->position_.pt);
    kps_current.push_back(kp->position_.pt);
}

10.cv::KeyPoint构造函数

@param _pt x & y coordinates of the keypoint
    @param _size keypoint diameter
    @param _angle keypoint orientation
    @param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
    @param _octave pyramid octave in which the keypoint has been detected
    @param _class_id object id
     */
    KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);

11.cv::calcOpticalFlowPyrLK

头文件
cv::TermCriteria类
定义迭代算法终止条件的类。
TermCriteria类定义在 /core/types.hpp 中

成员变量
enum
{
COUNT=1, //计算元素或者迭代次数最小值
MAX_ITER=COUNT, //最大迭代次数
EPS=2 //当满足该精确度时,迭代算法停止
};

构造函数
C++: TermCriteria::TermCriteria()
C++: TermCriteria::TermCriteria(int type, int maxCount, double epsilon)
C++: TermCriteria::TermCriteria(const CvTermCriteria& criteria)

参数:
type – 终止条件类型:
maxCount – 计算的迭代数或者最大元素数
epsilon – 当达到要求的精确度或参数的变化范围时,迭代算法停止

type可选:
TermCriteria::COUNT //达到最大迭代次数
TermCriteria::EPS //达到精度
TermCriteria::COUNT + TermCriteria::EPS //以上两种同时作为判定条件
参考:OpenCV cv::TermCriteria 模板类

12.cv::Mat()构造函数

cv::Mat mask(current_frame_->left_img_.size(),CV_8UC1,255);
    /** @overload
    @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the
    number of columns go in the reverse order.
    @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
    CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
    @param s An optional value to initialize each matrix element with. To set all the matrix elements to
    the particular value after the construction, use the assignment operator
    Mat::operator=(const Scalar& value) .
      */
    Mat(Size size, int type, const Scalar& s);

例子:OpenCV学习笔记(3)——Scalar数据类型理解
Scalar常用的使用场景如下:

Mat M(7,7,CV_32FC2,Scalar(1,3));

上面的代码表示:创建一个2通道,且每个通道的值都为(1,3),深度为32,7行7列的图像矩阵。CV_32F表示每个元素的值的类型为32位浮点数,C2表示通道数为2,Scalar(1,3)表示对矩阵每个元素都赋值为(1,3),第一个通道中的值都是1,第二个通道中的值都是3.
CV_8UC1:
预定义类型的结构如下所示:
CV_<bit_depth>(S|U|F)C<number_of_channels>
1–bit_depth—比特数—代表8bite,16bites,32bites,64bites—举个例子吧–比如说,如
如果你现在创建了一个存储–灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张
灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位–所以它对
应的就是CV_8
2–S|U|F–S–代表—signed int—有符号整形
U–代表–unsigned int–无符号整形
F–代表–float---------单精度浮点型
3–C<number_of_channels>----代表—一张图片的通道数,比如:
1–灰度图片–grayImg—是–单通道图像
2–RGB彩色图像---------是–3通道图像
3–带Alph通道的RGB图像–是–4通道图像
参考连接:Opencv 中 CV_8UC1,CV_32FC3等参数的含义

13.rectangle

cv::rectangle(mask,feat->position_.pt-cv::Point2f(10,10),
                          feat->position_.pt+cv::Point2f(10,10),0,CV_FILLED);

CV_FILLED为负数,绘制实心图形

CV_EXPORTS_W void rectangle(InputOutputArray img, Point pt1, Point pt2,
                          const Scalar& color, int thickness = 1,
                          int lineType = LINE_8, int shift = 0);

14.cv::detect()

占个坑

15.int Frontend::DetectFeatures()

mask作用:?
执行这个函数前,就已经有特征点了么?????????????

16.for (auto &landmark: landmarks)和for (auto &obs:observations)的嵌套循环

思考这层嵌套是啥关系??

for (auto &landmark: landmarks)
        {
            if (landmark.second->is_outlier_) continue;
            unsigned long landmark_id = landmark.second->id_;
            auto observations = landmark.second->GetObs();
            for (auto &obs:observations)
            {
                if (obs.lock() == nullptr) continue;
                auto feat = obs.lock();
                if (feat->is_outlier_ || feat->frame_.lock() == nullptr) continue;
                ...
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值