目录
接着我们来看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!