ORB-SLAM3的源码学习: Settings.cc:Settings::readCamera1/readCamera2 ...

打印 上一主题 下一主题

主题 829|帖子 829|积分 2487

前言

需要从设置文件yaml文件中读取相机参数才气用于后续计算。
1.函数声明

读取相机1的参数: 
  1. void Settings::readCamera1(cv::FileStorage &fSettings)
复制代码
如果是双目相机则还要读取相机2的参数:
  1. void Settings::readCamera2(cv::FileStorage &fSettings)
复制代码
2.函数定义 

相机1

1.读取相机模型

3的模型参加了针孔相机模型以及广角相机模型,可以利用模板函数读取参数,来确定相机的类型。
  1. bool found;
  2.     // Read camera model
  3.     string cameraModel = readParameter<string>(fSettings, "Camera.type", found);
复制代码
2.如果是针孔相机模型

就进行如下操纵:
读取相机参数构造相机模型,针对差别畸变参数的个数采用差别的方式进行读取,如果是单目相机和RGBD相机的话就需要进行去畸变操纵。
  1. vector<float> vCalibration;
  2.     if (cameraModel == "PinHole")
  3.     {
  4.         cameraType_ = PinHole;//设置相机类型
  5.         // Read intrinsic parameters读取内参
  6.         float fx = readParameter<float>(fSettings, "Camera1.fx", found);
  7.         float fy = readParameter<float>(fSettings, "Camera1.fy", found);
  8.         float cx = readParameter<float>(fSettings, "Camera1.cx", found);
  9.         float cy = readParameter<float>(fSettings, "Camera1.cy", found);
  10.         vCalibration = {fx, fy, cx, cy};//储存在校准的变量中
  11.         calibration1_ = new Pinhole(vCalibration);
  12.         originalCalib1_ = new Pinhole(vCalibration);
  13.         // Check if it is a distorted PinHole
  14.         // 检查这个针孔相机的配置文件是否有畸变参数
  15.         readParameter<float>(fSettings, "Camera1.k1", found, false);
  16.         if (found)
  17.         {
  18.             readParameter<float>(fSettings, "Camera1.k3", found, false);
  19.             if (found)
  20.             {
  21.                 vPinHoleDistorsion1_.resize(5);//储存相机畸变参数的向量扩容。
  22.                 vPinHoleDistorsion1_[4] = readParameter<float>(fSettings, "Camera1.k3", found);
  23.             }
  24.             else
  25.             {
  26.                 vPinHoleDistorsion1_.resize(4);
  27.             }
  28.             vPinHoleDistorsion1_[0] = readParameter<float>(fSettings, "Camera1.k1", found);
  29.             vPinHoleDistorsion1_[1] = readParameter<float>(fSettings, "Camera1.k2", found);
  30.             vPinHoleDistorsion1_[2] = readParameter<float>(fSettings, "Camera1.p1", found);
  31.             vPinHoleDistorsion1_[3] = readParameter<float>(fSettings, "Camera1.p2", found);
  32.         }
  33.         // Check if we need to correct distortion from the images
  34.         // 如果是单目相机或者是RGBD相机且有畸变参数则需要去畸变操作。
  35.         if (
  36.             (sensor_ == System::MONOCULAR ||
  37.                 sensor_ == System::IMU_MONOCULAR ||
  38.                 sensor_ == System::RGBD ||
  39.                 sensor_ == System::IMU_RGBD) &&
  40.             vPinHoleDistorsion1_.size() != 0)
  41.         {
  42.             bNeedToUndistort_ = true;
  43.         }
  44.     }
复制代码
 3.如果是矫正后的图像

此时认为是没有畸变的,就正常读取参数构造相机模型即可。
  1. //如果是校正后的图像则认为没畸变。
  2.     else if (cameraModel == "Rectified")
  3.     {
  4.         cameraType_ = Rectified;
  5.         // Read intrinsic parameters
  6.         float fx = readParameter<float>(fSettings, "Camera1.fx", found);
  7.         float fy = readParameter<float>(fSettings, "Camera1.fy", found);
  8.         float cx = readParameter<float>(fSettings, "Camera1.cx", found);
  9.         float cy = readParameter<float>(fSettings, "Camera1.cy", found);
  10.         vCalibration = {fx, fy, cx, cy};
  11.         calibration1_ = new Pinhole(vCalibration);
  12.         originalCalib1_ = new Pinhole(vCalibration);
  13.         // Rectified images are assumed to be ideal PinHole images (no distortion)
  14.     }
复制代码
4.如果是广角相机模型

需要在读取相机参数构建相机模型的基础上如果双目模式则要加上重叠区域参数读取以及构建重叠区域。
  1. else if (cameraModel == "KannalaBrandt8")
  2.     {
  3.         cameraType_ = KannalaBrandt;
  4.         // Read intrinsic parameters
  5.         // 用模板函数读取yaml文件中的参数
  6.         float fx = readParameter<float>(fSettings, "Camera1.fx", found);
  7.         float fy = readParameter<float>(fSettings, "Camera1.fy", found);
  8.         float cx = readParameter<float>(fSettings, "Camera1.cx", found);
  9.         float cy = readParameter<float>(fSettings, "Camera1.cy", found);
  10.         float k0 = readParameter<float>(fSettings, "Camera1.k1", found);
  11.         float k1 = readParameter<float>(fSettings, "Camera1.k2", found);
  12.         float k2 = readParameter<float>(fSettings, "Camera1.k3", found);
  13.         float k3 = readParameter<float>(fSettings, "Camera1.k4", found);
  14.         vCalibration = {fx, fy, cx, cy, k0, k1, k2, k3};
  15.         calibration1_ = new KannalaBrandt8(vCalibration);
  16.         originalCalib1_ = new KannalaBrandt8(vCalibration);
  17.         //双目相机或IMU双目相机时,读取和设置摄像头的图像重叠区域参数。
  18.         if (sensor_ == System::STEREO || sensor_ == System::IMU_STEREO)
  19.         {
  20.             int colBegin = readParameter<int>(fSettings, "Camera1.overlappingBegin", found);
  21.             int colEnd = readParameter<int>(fSettings, "Camera1.overlappingEnd", found);
  22.             vector<int> vOverlapping = {colBegin, colEnd};//摄像头重叠区域。
  23.             static_cast<KannalaBrandt8 *>(calibration1_)->mvLappingArea = vOverlapping;
  24.         }
  25.     }
复制代码
5.如果没有读取到相机模型

直接输堕落误信息。
  1. else
  2.     {
  3.         cerr << "Error: " << cameraModel << " not known" << endl;
  4.         exit(-1);
  5.     }
复制代码
完整的代码 

  1. void Settings::readCamera1(cv::FileStorage &fSettings){    bool found;
  2.     // Read camera model
  3.     string cameraModel = readParameter<string>(fSettings, "Camera.type", found);    vector<float> vCalibration;
  4.     if (cameraModel == "PinHole")
  5.     {
  6.         cameraType_ = PinHole;//设置相机类型
  7.         // Read intrinsic parameters读取内参
  8.         float fx = readParameter<float>(fSettings, "Camera1.fx", found);
  9.         float fy = readParameter<float>(fSettings, "Camera1.fy", found);
  10.         float cx = readParameter<float>(fSettings, "Camera1.cx", found);
  11.         float cy = readParameter<float>(fSettings, "Camera1.cy", found);
  12.         vCalibration = {fx, fy, cx, cy};//储存在校准的变量中
  13.         calibration1_ = new Pinhole(vCalibration);
  14.         originalCalib1_ = new Pinhole(vCalibration);
  15.         // Check if it is a distorted PinHole
  16.         // 检查这个针孔相机的配置文件是否有畸变参数
  17.         readParameter<float>(fSettings, "Camera1.k1", found, false);
  18.         if (found)
  19.         {
  20.             readParameter<float>(fSettings, "Camera1.k3", found, false);
  21.             if (found)
  22.             {
  23.                 vPinHoleDistorsion1_.resize(5);//储存相机畸变参数的向量扩容。
  24.                 vPinHoleDistorsion1_[4] = readParameter<float>(fSettings, "Camera1.k3", found);
  25.             }
  26.             else
  27.             {
  28.                 vPinHoleDistorsion1_.resize(4);
  29.             }
  30.             vPinHoleDistorsion1_[0] = readParameter<float>(fSettings, "Camera1.k1", found);
  31.             vPinHoleDistorsion1_[1] = readParameter<float>(fSettings, "Camera1.k2", found);
  32.             vPinHoleDistorsion1_[2] = readParameter<float>(fSettings, "Camera1.p1", found);
  33.             vPinHoleDistorsion1_[3] = readParameter<float>(fSettings, "Camera1.p2", found);
  34.         }
  35.         // Check if we need to correct distortion from the images
  36.         // 如果是单目相机或者是RGBD相机且有畸变参数则需要去畸变操作。
  37.         if (
  38.             (sensor_ == System::MONOCULAR ||
  39.                 sensor_ == System::IMU_MONOCULAR ||
  40.                 sensor_ == System::RGBD ||
  41.                 sensor_ == System::IMU_RGBD) &&
  42.             vPinHoleDistorsion1_.size() != 0)
  43.         {
  44.             bNeedToUndistort_ = true;
  45.         }
  46.     }    //如果是校正后的图像则认为没畸变。
  47.     else if (cameraModel == "Rectified")
  48.     {
  49.         cameraType_ = Rectified;
  50.         // Read intrinsic parameters
  51.         float fx = readParameter<float>(fSettings, "Camera1.fx", found);
  52.         float fy = readParameter<float>(fSettings, "Camera1.fy", found);
  53.         float cx = readParameter<float>(fSettings, "Camera1.cx", found);
  54.         float cy = readParameter<float>(fSettings, "Camera1.cy", found);
  55.         vCalibration = {fx, fy, cx, cy};
  56.         calibration1_ = new Pinhole(vCalibration);
  57.         originalCalib1_ = new Pinhole(vCalibration);
  58.         // Rectified images are assumed to be ideal PinHole images (no distortion)
  59.     }    else if (cameraModel == "KannalaBrandt8")
  60.     {
  61.         cameraType_ = KannalaBrandt;
  62.         // Read intrinsic parameters
  63.         // 用模板函数读取yaml文件中的参数
  64.         float fx = readParameter<float>(fSettings, "Camera1.fx", found);
  65.         float fy = readParameter<float>(fSettings, "Camera1.fy", found);
  66.         float cx = readParameter<float>(fSettings, "Camera1.cx", found);
  67.         float cy = readParameter<float>(fSettings, "Camera1.cy", found);
  68.         float k0 = readParameter<float>(fSettings, "Camera1.k1", found);
  69.         float k1 = readParameter<float>(fSettings, "Camera1.k2", found);
  70.         float k2 = readParameter<float>(fSettings, "Camera1.k3", found);
  71.         float k3 = readParameter<float>(fSettings, "Camera1.k4", found);
  72.         vCalibration = {fx, fy, cx, cy, k0, k1, k2, k3};
  73.         calibration1_ = new KannalaBrandt8(vCalibration);
  74.         originalCalib1_ = new KannalaBrandt8(vCalibration);
  75.         //双目相机或IMU双目相机时,读取和设置摄像头的图像重叠区域参数。
  76.         if (sensor_ == System::STEREO || sensor_ == System::IMU_STEREO)
  77.         {
  78.             int colBegin = readParameter<int>(fSettings, "Camera1.overlappingBegin", found);
  79.             int colEnd = readParameter<int>(fSettings, "Camera1.overlappingEnd", found);
  80.             vector<int> vOverlapping = {colBegin, colEnd};//摄像头重叠区域。
  81.             static_cast<KannalaBrandt8 *>(calibration1_)->mvLappingArea = vOverlapping;
  82.         }
  83.     }    else
  84.     {
  85.         cerr << "Error: " << cameraModel << " not known" << endl;
  86.         exit(-1);
  87.     }}
复制代码
相机2

这时候已经默认是双目模式了,除了要进行相机1的操纵,还要额外进行一些操纵。
读取基线,计算基线焦距,读取深度。
  1. // Load stereo extrinsic calibration
  2.     if (cameraType_ == Rectified)
  3.     {
  4.         b_ = readParameter<float>(fSettings, "Stereo.b", found);
  5.         bf_ = b_ * calibration1_->getParameter(0);
  6.     }
  7.     else
  8.     {
  9.         cv::Mat cvTlr = readParameter<cv::Mat>(fSettings, "Stereo.T_c1_c2", found);
  10.         Tlr_ = Converter::toSophus(cvTlr);
  11.         // TODO: also search for Trl and invert if necessary
  12.         b_ = Tlr_.translation().norm();
  13.         bf_ = b_ * calibration1_->getParameter(0);
  14.     }
  15.     thDepth_ = readParameter<float>(fSettings, "Stereo.ThDepth", found);
复制代码
完整的代码 

  1. void Settings::readCamera2(cv::FileStorage &fSettings){    bool found;    vector<float> vCalibration;    if (cameraType_ == PinHole)    {        bNeedToRectify_ = true;        // Read intrinsic parameters        float fx = readParameter<float>(fSettings, "Camera2.fx", found);        float fy = readParameter<float>(fSettings, "Camera2.fy", found);        float cx = readParameter<float>(fSettings, "Camera2.cx", found);        float cy = readParameter<float>(fSettings, "Camera2.cy", found);        vCalibration = {fx, fy, cx, cy};        calibration2_ = new Pinhole(vCalibration);        originalCalib2_ = new Pinhole(vCalibration);        // Check if it is a distorted PinHole        readParameter<float>(fSettings, "Camera2.k1", found, false);        if (found)        {            readParameter<float>(fSettings, "Camera2.k3", found, false);            if (found)            {                vPinHoleDistorsion2_.resize(5);                vPinHoleDistorsion2_[4] = readParameter<float>(fSettings, "Camera2.k3", found);            }            else            {                vPinHoleDistorsion2_.resize(4);            }            vPinHoleDistorsion2_[0] = readParameter<float>(fSettings, "Camera2.k1", found);            vPinHoleDistorsion2_[1] = readParameter<float>(fSettings, "Camera2.k2", found);            vPinHoleDistorsion2_[2] = readParameter<float>(fSettings, "Camera2.p1", found);            vPinHoleDistorsion2_[3] = readParameter<float>(fSettings, "Camera2.p2", found);        }    }    else if (cameraType_ == KannalaBrandt)    {        // Read intrinsic parameters        float fx = readParameter<float>(fSettings, "Camera2.fx", found);        float fy = readParameter<float>(fSettings, "Camera2.fy", found);        float cx = readParameter<float>(fSettings, "Camera2.cx", found);        float cy = readParameter<float>(fSettings, "Camera2.cy", found);        float k0 = readParameter<float>(fSettings, "Camera1.k1", found);        float k1 = readParameter<float>(fSettings, "Camera1.k2", found);        float k2 = readParameter<float>(fSettings, "Camera1.k3", found);        float k3 = readParameter<float>(fSettings, "Camera1.k4", found);        vCalibration = {fx, fy, cx, cy, k0, k1, k2, k3};        calibration2_ = new KannalaBrandt8(vCalibration);        originalCalib2_ = new KannalaBrandt8(vCalibration);        int colBegin = readParameter<int>(fSettings, "Camera2.overlappingBegin", found);        int colEnd = readParameter<int>(fSettings, "Camera2.overlappingEnd", found);        vector<int> vOverlapping = {colBegin, colEnd};        static_cast<KannalaBrandt8 *>(calibration2_)->mvLappingArea = vOverlapping;    }    // Load stereo extrinsic calibration
  2.     if (cameraType_ == Rectified)
  3.     {
  4.         b_ = readParameter<float>(fSettings, "Stereo.b", found);
  5.         bf_ = b_ * calibration1_->getParameter(0);
  6.     }
  7.     else
  8.     {
  9.         cv::Mat cvTlr = readParameter<cv::Mat>(fSettings, "Stereo.T_c1_c2", found);
  10.         Tlr_ = Converter::toSophus(cvTlr);
  11.         // TODO: also search for Trl and invert if necessary
  12.         b_ = Tlr_.translation().norm();
  13.         bf_ = b_ * calibration1_->getParameter(0);
  14.     }
  15.     thDepth_ = readParameter<float>(fSettings, "Stereo.ThDepth", found);}
复制代码
结束语

以上就是我学习到的内容,如果对您有资助请多多支持我,如果那里有题目接待大家在批评区积极讨论,我看到会及时回复。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曹旭辉

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表