DS-SLAM代码解析和问题整理 (四)


接着我们来看Segment.cc有哪些内容

Segment::Segment

首先是Segement的构造函数

Segment::Segment(const string &pascal_prototxt, const string &pascal_caffemodel, const string &pascal_png):mbFinishRequested(false),mSkipIndex(SKIP_NUMBER),mSegmentTime(0),imgIndex(0)
{

    model_file = pascal_prototxt;        // 模型文件,网络模型 ..../ORB_SLAM2_PointMap_SegNetM/prototxts/segnet_pascal.prototxt
    trained_file = pascal_caffemodel;    // 训练文件,训练好的参数 ..../ORB_SLAM2_PointMap_SegNetM/models/segnet_pascal.caffemodel
    LUT_file = pascal_png;               // 调色板   ..../ORB_SLAM2_PointMap_SegNetM/tools/pascal.png
    label_colours = cv::imread(LUT_file,1);     // 标签颜色
    //cv::imread("label_colours",label_colours);
    cv::cvtColor(label_colours, label_colours, CV_RGB2BGR);  // 格式转换

    mImgSegmentLatest=cv::Mat(Camera::height,Camera::width,CV_8UC1); // 语义掩膜(无颜色)
    mbNewImgFlag=false;

}

Segment::SetTracker

设置Tracking线程的指针

void Segment::SetTracker(Tracking *pTracker)
{
    mpTracker=pTracker;
}

Segment::isNewImgArrived

查看是否有新的图像帧进入

bool Segment::isNewImgArrived()
{
    unique_lock<mutex> lock(mMutexGetNewImg);
    if(mbNewImgFlag)
    {
        mbNewImgFlag=false;
        return true;
    }
    else
    return false;
}

Segment::Run() 重点关注

函数的源头是System.cc中的

 mptSegment =new thread(&ORB_SLAM2::Segment::Run,mpSegment);

由此开启segment线程.

这个函数主要执行了

  • step1.新建一个分类器classifier
  • step2. 跳过第0帧图像
    • step 2.1 通过caffe框架的Predict函数完成语义分割,得到语义分割的结果mImgSegment(运行结果是一个语义分割后的黑色掩模)
    • step 2.2 将单通道的灰度图转化为三通道的 RGB图 ,但是图像虽然还是灰色的,但是已经是三通道的了
    • step 2.3 将像素进行映射,使用了Opencv中的LUT函数,运行之后语义分割的图片 有了颜色
    • step 2.4 将原图象和分割后的图像 都resize成相同的尺寸
    • step 2.5 计算单次语义分割处理的时间
  • step 3 保存了上一帧和本帧的分割图片mImgSegmentLatest,并且告诉Track新的分割图片已经就绪

接下来我们来仔细分析一下这个函数:

  • 首先函数新建了一个分类器
 classifier=new Classifier(model_file, trained_file); // 调用了caffe的接口
  • 检查是否是最新一帧图像
while(1)
    {
        usleep(1);
        if(!isNewImgArrived()) // 是否是新的一帧图像
        continue;
  • 通过caffe框架的Predict函数完成语义分割,得到语义分割的结果mImgSegment(运行结果是一个语义分割后的黑色掩模)
mImgSegment=classifier->Predict(mImg, label_colours);

在这里插入图片描述

  • 将单通道的灰度图转化为三通道的 RGB图 ,但是图像虽然还是灰色的,但是已经是三通道的了
cv::cvtColor(mImgSegment,mImgSegment_color, CV_GRAY2BGR);

在这里插入图片描述

  • 将像素进行映射,使用了Opencv中的LUT函数,运行之后语义分割的图片 有了颜色
LUT(mImgSegment_color, label_colours, mImgSegment_color_final); // mImgSegment图片是灰色的,没有颜色,经过调色版上色之后得到mImgSegment_color_final

在这里插入图片描述

  • 将原图象和分割后的图像 都resize成相同的尺寸
cv::resize(mImgSegment, mImgSegment, cv::Size(Camera::width,Camera::height) );

cv::resize(mImgSegment_color_final, mImgSegment_color_final, cv::Size(Camera::width,Camera::height) );

在这里插入图片描述
在这里插入图片描述

  • 计算单次语义分割处理的时间
mSegmentTime+=std::chrono::duration_cast<std::chrono::duration<double> >(t4 - t3).count();
mSkipIndex=0;
imgIndex++;
  • 保存了上一帧和本帧的分割图片mImgSegmentLatest,并且告诉Track新的分割图片已经就绪
ProduceImgSegment();
if(CheckFinish()) // 停止的flag
{
    break;
}

Segment::CheckFinish()

检查Segment是否完成

bool Segment::CheckFinish()
{
    unique_lock<mutex> lock(mMutexFinish);
    return mbFinishRequested;
}

Segment::RequestFinish

外部请求停止

void Segment::RequestFinish()
{
    unique_lock<mutex> lock(mMutexFinish);
    mbFinishRequested=true;
}

Segment::ProduceImgSegment

保存了上一帧和本帧的分割图片mImgSegmentLatest,并且告诉Track新的分割图片已经就绪

void Segment::ProduceImgSegment()
{
    std::unique_lock <std::mutex> lock(mMutexNewImgSegment);
    mImgTemp=mImgSegmentLatest;
    mImgSegmentLatest=mImgSegment;
    mImgSegment=mImgTemp;
    mpTracker->mbNewSegImgFlag=true;
}

cv::Mat mImg;
cv::Mat mImgTemp; // 存储最新一帧上一帧图像的临时变量
cv::Mat mImgSegment_color; // 三通道的但颜色依然是黑色的语义掩模
cv::Mat mImgSegment_color_final; // 彩色的语义掩模
cv::Mat mImgSegment; // 语义分割后的黑色掩模
cv::Mat mImgSegmentLatest; // 语义掩模(无颜色)
Tracking* mpTracker; // 跟踪线程的指针

以上就是DS-SLAM 的Segment.cc解析的全部内容,Thanks for reading!

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值