DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络

目录

1.执行例程rgbd_tum

2.SegmentDynObject::SegmentDynObject方法

3. SegmentDynObject::GetSegmentation

4.初始化SLAM系统


1.执行例程rgbd_tum

/home/lhwnb/Desktop/slam/DynaSLAM/Examples/RGB-D/rgbd_tum 
/home/lhwnb/Desktop/slam/DynaSLAM/Vocabulary/ORBvoc.txt 
/home/lhwnb/Desktop/slam/DynaSLAM/Examples/RGB-D/TUM1.yaml 
/home/lhwnb/Desktop/slam/DynaSLAM/dataset/rgbd_dataset_freiburg1_xyz/ 
/home/lhwnb/Desktop/slam/DynaSLAM/dataset/assciation.txt 
/home/lhwnb/Desktop/slam/DynaSLAM/dataset/mask/ 
/home/lhwnb/Desktop/slam/DynaSLAM/dataset/output/

        执行例程的时候输入到CLion中的程序实参是这样的:

DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络_第1张图片

        分别对应着RGB例程的可执行文件、ORB字典的路径、相机的配置文件、数据集、深度图和RGB图的对齐文件、mask目录(可选)、output目录(可选)。

        如果不指定mask目录和output目录,则程序的执行和ORB-SLAM2无区别。

        通过LoadImage函数将RGB图像读入vstrImageFilenamesRGB中,深度图读入vstrImageFilenamesD中,时间戳读入vTimestamps中。

        随后测试Mask R-CNN网络是否可用:

    // Initialize 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;
    }
%YAML:1.0
py_path: "./src/python/"
module_name: "MaskRCNN"
class_name: "Mask"
get_dyn_seg: "GetDynSeg"

       主要是加载了几个参数:

        @py_path : src/python目录

        @module_name : MaskRCNN文件

DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络_第2张图片

         @class_name:Mask类DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络_第3张图片

         @get_dyn_seg:GetDynSeg MaskRCNN.py中Mask类的方法

DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络_第4张图片        

2.SegmentDynObject::SegmentDynObject方法

SegmentDynObject::SegmentDynObject(){
    std::cout << "Importing Mask R-CNN Settings..." << std::endl;
    ImportSettings();
    std::string x;
    setenv("PYTHONPATH", this->py_path.c_str(), 1);
    x = getenv("PYTHONPATH");
    Py_Initialize();
    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;
    cv::Mat image  = cv::Mat::zeros(480,640,CV_8UC3); //Be careful with size!!
    std::cout << "Loading net parameters..." << std::endl;
    GetSegmentation(image);
}

        SegmentDynObject::SegmentDynObject方法是加载Mask R-CNN网络的参数并测试网络是否有效并实例化GetDynSeg方法,如果python部分没配置正确的画在这里会报段错误。

        setenv起到改变或增加环境变量的作用,用法如下:

        int setenv(const char *name,const char * value,int overwrite);

        @name为环境变量名称字符串。
        @value则为变量内容。

        @overwrite用来决定是否要改变已存在的环境变量。

        如果overwrite不为0,则改变环境变量原有内容,原有内容会被改为参数value所指的变量内容。如果overwrite为0,且该环境变量已有内容,则参数value会被忽略。
        @return 执行成功则返回0,有错误发生时返回-1。
        这是例子:

#include
main()
{
  char * p;
  if((p=getenv(“USER”)))
      printf(“USER =%s\n”,p);
  setenv(“USER”,”test”,1);
  printf(“USER=%s\n”,getenv(“USEr”));
  unsetenv(“USER”);
  printf(“USER=%s\n”,getenv(“USER”));
}

        执行结果:USER = root        USER = test          USER = (null)

        py_module 的类型是PyObject *类型,通过PyImport_ImportModule方法读入src/python目录下的MaskRCNN.py文件,如果读入文件为空报错。

        py_class 的类型是PyObject *类型,通过PyObject_GetAttrString方法导入已导入模块(MaskRCNN.py)中的方法或类(MaskRCNN.py中的Mask类)。

        net  的类型是PyObject *类型,通过PyInstance_New方法使用类构造对象。

        这样我们顺利地构造了MaskRCNN.py中的Mask类。

        下面我们创建网络实例:Creating net instance....,首先创建一个480*640的空白图像。

        调用GetSegmentation函数对该张图片进行处理。

3. SegmentDynObject::GetSegmentation

cv::Mat SegmentDynObject::GetSegmentation(cv::Mat &image,std::string dir, std::string name){
    cv::Mat seg = cv::imread(dir+"/"+name,CV_LOAD_IMAGE_UNCHANGED);
    if(seg.empty()){
        PyObject* py_image = cvt->toNDArray(image.clone());
        assert(py_image != NULL);
        PyObject* py_mask_image = PyObject_CallMethod(this->net, const_cast(this->get_dyn_seg.c_str()),"(O)",py_image);
        seg = cvt->toMat(py_mask_image).clone();
        seg.cv::Mat::convertTo(seg,CV_8U);//0 background y 1 foreground
        if(dir.compare("no_save")!=0){
            DIR* _dir = opendir(dir.c_str());
            if (_dir) {closedir(_dir);}
            else if (ENOENT == errno)
            {
                const int check = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
                if (check == -1) {
                    std::string str = dir;
                    str.replace(str.end() - 6, str.end(), "");
                    mkdir(str.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
                }
            }
            cv::imwrite(dir+"/"+name,seg);
        }
    }
    return seg;
}

        本方法将传入的image调用MaskRCNN.py中的GetDynSeg方法进行语义分割,得到动态掩码图。

DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络_第5张图片 图 - 图中白色的为先验动态物体  0 for background and 1 for foreground

         首先将image图片转换成tensor格式存储在py_image在,判断是否读取成功。

        通过PyObject_CallMethod方法调用(this -> net 是MaskRCNN.py中Mask类实例化的一个对象,this->get_dyn_seg 是该类中的一个方法求得图像的mask信息,再将其转化成图片格式保存起来。返回图像。

        现在Mask R-CNN网络初始化完毕,屏幕输出Mask net loaded!。

4.初始化SLAM系统

        这部分和双目相同,详情见博客:

DynaSLAM-8 DynaSLAM中双目运行流程(Ⅱ):初始化SLAM系统部分System.ccicon-default.png?t=N0U7https://blog.csdn.net/qq_41694024/article/details/128843822        初始化

    // Dilation settings
    int dilation_size = 15;
    cv::Mat kernel = getStructuringElement(cv::MORPH_ELLIPSE,
                                           cv::Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                           cv::Point( dilation_size, dilation_size ) );

        关于Dilate它的本质是取邻域的最大值(是和像素值有关的)。

    if (argc==7)
    {
        std::string dir = string(argv[6]);
        mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
        dir = string(argv[6]) + "/rgb/";
        mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
        dir = string(argv[6]) + "/depth/";
        mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
        dir = string(argv[6]) + "/mask/";
        mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    }

        如果输入的参数是7个,即调用Mask R-CNN网络的情况下,创建几个目录:

DynaSLAM-11 DynaSLAM中RGB-D运行流程(Ⅰ):调用Mask 初始化R-CNN网络_第6张图片

 

你可能感兴趣的:(DynaSLAM,代码解析,python,计算机视觉,c++,人工智能)