DynaSLAM语义分割部分C++详解

以TUM-RGB-D数据集为例

rgbd_tum.cc中的main函数中,前面读取图片部分与ORB-SLAM2的代码基本一致。
根据传入的参数个数(argc的值),其算法的流程也会改变。
传入5个参数:就与普通的ORB-SLAM2无差别
传入6个参数:就会将MASK R-CNN得到的MASK图像存储到第6个参数的文件夹中,然后创建一个名为output的文件夹存储最后结果,其中存储Mask和去除动态物体后的depth和rgb图像。
传入7个参数:会将MASK图像存储到第6 个参数的文件夹中,将去除动态物体后的结果存到output文件夹中。

 // Initialize Mask R-CNN
 //进行Mask R-CNN初始化
    DynaSLAM::SegmentDynObject *MaskNet;
    if (argc==6 || argc==7)
    {
        cout << "Loading Mask R-CNN. This could take a while..." << endl;
        //初始化一个语义分割的类
        MaskNet = new DynaSLAM::SegmentDynObject();
        cout << "Mask R-CNN loaded!" << endl;
    }

接着看MaskNet.cc中的SegmentDynObject::SegmentDynObject()函数,这个函数的主要功能就是配置Python环境,初始化Python编译器,并将python文件中的类初始化。以便下一步使用Mask R-CNN进行语义分割。

SegmentDynObject::SegmentDynObject(){
    std::cout << "Importing Mask R-CNN Settings..." << std::endl;
    //传入Python相关的参数
    ImportSettings();
    std::string x;
    //设置当前python的环境
    setenv("PYTHONPATH", this->py_path.c_str(), 1);
    x = getenv("PYTHONPATH");
    //初始化Python编译器
    Py_Initialize();
    //cv::Mat与Python的np.array互相转换的函数
    this->cvt = new NDArrayConverter();
    this->py_module = PyImport_ImportModule(this->module_name.c_str());
    assert(this->py_module != NULL);
    this->py_class = PyObject_GetAttrString(this->py_module, this->class_name.c_str());
    assert(this->py_class != NULL);
    this->net = PyInstance_New(this->py_class, NULL, NULL);
    assert(this->net != NULL);
    std::cout << "Creating net instance..." << std::endl;
    //生成一个空的mask空白RGB矩阵存放mask
    cv::Mat image  = cv::Mat::zeros(480,640,CV_8UC3); //Be careful with size!!
    std::cout << "Loading net parameters..." << std::endl;
    //在image中存储,0为静态物体,1为动态物体
    GetSegmentation(image);
}

在DynaSLAM中是使用python进行语义分割,然后把前端语义分割部分与C++写的ORB-SLAM2结合起来的。

现在看传入Python相关参数的ImportSettings()函数,在MaskNet.cc文件中

void SegmentDynObject::ImportSettings(){
	//string存储Python参数.yaml文件的地址
    std::string strSettingsFile = "./Examples/RGB-D/MaskSettings.yaml";
    //读取文件中的参数
    cv::FileStorage fs(strSettingsFile.c_str(), cv::FileStorage::READ);
    //Python文件的地址
    fs["py_path"] >> this->py_path;
    //模块的名称
    fs["module_name"] >> this->module_name;
   //类名
    fs["class_name"] >> this->class_name;
    //存储需要调用的python函数名称
    fs["get_dyn_seg"] >> this->get_dyn_seg;

}

这个.yaml文件中的内容
MaskSettings.yaml

Tips: 在C++中使用Python的一般过程

膨胀操作

在后面会对语义分割得到的Mask图像进行膨胀操作:
膨胀操作就是将属于动态物体的范围进一步扩大,因为在动态物体边缘的特征点也是无法使用的,会降低系统的精度。
Example:
在这里插入图片描述
进行膨胀操作的过程

 // Dilation settings
 //膨胀操作的核矩阵初始化
int dilation_size = 15;
//getStructuringElement函数来初始化,第一个参数为选择核的形状,这里选择的是椭圆形。第二参数为选择核的大小,第三个参数为选择核的中心点位置
cv::Mat kernel = getStructuringElement(cv::MORPH_ELLIPSE,
                                       cv::Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       cv::Point( dilation_size, dilation_size ) );
/*
.......
......
*/
//maskRCNN数值在0~1之间,动态物体的mask对应的像素值为1
// Segment out the images
cv::Mat mask = cv::Mat::ones(480,640,CV_8U);
if (argc == 6 || argc == 7)
{
    cv::Mat maskRCNN;
    //GetSegmantation参数:RGB图像,Mask路径,图片保存名称
    maskRCNN = MaskNet->GetSegmentation(imRGB,string(argv[5]),vstrImageFilenamesRGB[ni].replace(0,4,""));
    cv::Mat maskRCNNdil = maskRCNN.clone();
    //进行膨胀操作
    cv::dilate(maskRCNN,maskRCNNdil, kernel);
    //将原图与膨胀得到的相减,1表示静态物体
    mask = mask - maskRCNNdil;
        }
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值