2021SC@SDUSC
Viewer.cc
引用Viewer.h,pangolin可视化库以及互斥量mutex类;在Viewer.h中,定义了类Viewer,类中public声明了主线程函数:绘制点、关键帧、当前摄相机状态和最后处理的帧。根据摄影机fps刷新图形。声明运行方法,站厅请求和终止请求,进程释放及设置任务暂停点;private声明了检查结束状态及设置结束。
class Viewer
{
public:
Viewer(System* pSystem, FrameDrawer* pFrameDrawer, MapDrawer* pMapDrawer, Tracking *pTracking, const string &strSettingPath);
void Run();
void RequestFinish();
void RequestStop();
bool isFinished();
bool isStopped();
bool isStepByStep();
void Release();
void SetTrackingPause();
bool both;
private:
bool ParseViewerParamFile(cv::FileStorage &fSettings);
bool Stop();
System* mpSystem;
FrameDrawer* mpFrameDrawer;
MapDrawer* mpMapDrawer;
Tracking* mpTracker;
// 1/fps in ms
double mT;
float mImageWidth, mImageHeight;
float mViewpointX, mViewpointY, mViewpointZ, mViewpointF;
bool CheckFinish();
void SetFinish();
bool mbFinishRequested;
bool mbFinished;
std::mutex mMutexFinish;
bool mbStopped;
bool mbStopRequested;
std::mutex mMutexStop;
bool mbStopTrack;
};
在Viewer.cc中,具体定义了这些函数及所传递的参数,使用了pangolin库及OpenCV中的一些方法。
void Viewer::Run()
{
mbFinished = false;
mbStopped = false;
pangolin::CreateWindowAndBind("ORB-SLAM3: Map Viewer",1024,768);
// 3D 鼠标处理程序需要启用深度测试
glEnable(GL_DEPTH_TEST);
// 可能遇到的使用到 OpenGl 的情况
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pangolin::CreatePanel("menu").SetBounds(0.0,1.0,0.0,pangolin::Attach::Pix(175));
pangolin::Var<bool> menuFollowCamera("menu.Follow Camera",true,true);
pangolin::Var<bool> menuCamView("menu.Camera View",false,false);
pangolin::Var<bool> menuTopView("menu.Top View",false,false);
pangolin::Var<bool> menuShowPoints("menu.Show Points",true,true);
pangolin::Var<bool> menuShowKeyFrames("menu.Show KeyFrames",true,true);
pangolin::Var<bool> menuShowGraph("menu.Show Graph",false,true);
pangolin::Var<bool> menuShowInertialGraph("menu.Show Inertial Graph",true,true);
pangolin::Var<bool> menuLocalizationMode("menu.Localization Mode",false,true);
pangolin::Var<bool> menuReset("menu.Reset",false,false);
// 定义摄影机渲染对象(用于视图/场景浏览)
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,1000),
pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0)
);
// 将命名的OpenGL视图添加到窗口并提供3D处理程序
pangolin::View& d_cam = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(175), 1.0, -1024.0f/768.0f)
.SetHandler(new pangolin::Handler3D(s_cam));
pangolin::OpenGlMatrix Twc, Twr;
Twc.SetIdentity();
pangolin::OpenGlMatrix Ow; // 在z轴上以g为正方向
Ow.SetIdentity();
pangolin::OpenGlMatrix Twwp; // 在z轴上以g为正方向, 但x和y在相机中
Twwp.SetIdentity();
cv::namedWindow("ORB-SLAM3: Current Frame");
/*
* Camera Axis:
* X - Right, Y - Up, Z - Back
* Image Origin:
* Bottom Left
* ProjectionMatrix为投影矩阵
* 第一组eyex, eyey,eyez 相机在世界坐标的位置
* 第二组centerx,centery,centerz 相机镜头对准的物体在世界坐标的位置
* 第三组upx,upy,upz 相机向上的方向在世界坐标中的方向
* 你把相机想象成为你自己的脑袋:
* 第一组数据就是脑袋的位置
* 第二组数据就是眼睛看的物体的位置
* 第三组就是头顶朝向的方向(因为你可以歪着头看同一个物体)。
* mViewpointX: 0
* mViewpointY: -0.7
* mViewpointZ: -1.8
*/
bool bFollow = true;
bool bLocalizationMode = false;
bool bStepByStep = false;
bool bCameraView = true;
if(mpTracker->mSensor == mpSystem->MONOCULAR || mpTracker->mSensor == mpSystem->STEREO || mpTracker->mSensor == mpSystem->RGBD)
{
menuShowGraph = true;
}
while(1)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mpMapDrawer->GetCurrentOpenGLCameraMatrix(Twc,Ow,Twwp);
if(mbStopTrack)
{
mbStopTrack = false;
}
if(menuFollowCamera && bFollow)
{
if(bCameraView)
s_cam.Follow(Twc);
else
s_cam.Follow(Ow);
}
else if(menuFollowCamera && !bFollow)
{
if(bCameraView)
{
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,1000));
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0));
s_cam.Follow(Twc);
}
else
{
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,1000));
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,10, 0,0,0,0.0,0.0, 1.0));
s_cam.Follow(Ow);
}
bFollow = true;
}
else if(!menuFollowCamera && bFollow)
{
bFollow = false;
}
if(menuCamView)
{
menuCamView = false;
bCameraView = true;
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,10000));
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0));
s_cam.Follow(Twc);
}
if(menuTopView && mpMapDrawer->mpAtlas->isImuInitialized())
{
menuTopView = false;
bCameraView = false;
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,10000));
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,50, 0,0,0,0.0,0.0, 1.0));
s_cam.Follow(Ow);
}
if(menuLocalizationMode && !bLocalizationMode)
{
mpSystem->ActivateLocalizationMode();
bLocalizationMode = true;
}
else if(!menuLocalizationMode && bLocalizationMode)
{
mpSystem->DeactivateLocalizationMode();
bLocalizationMode = false;
}
d_cam.Activate(s_cam);
glClearColor(1.0f,1.0f,1.0f,1.0f);
mpMapDrawer->DrawCurrentCamera(Twc);
if(menuShowKeyFrames || menuShowGraph || menuShowInertialGraph)
mpMapDrawer->DrawKeyFrames(menuShowKeyFrames,menuShowGraph, menuShowInertialGraph);
if(menuShowPoints)
mpMapDrawer->DrawMapPoints();
pangolin::FinishFrame();
cv::Mat toShow;
cv::Mat im = mpFrameDrawer->DrawFrame(true);
if(both){
cv::Mat imRight = mpFrameDrawer->DrawRightFrame();
cv::hconcat(im,imRight,toShow);
}
else{
toShow = im;
}
cv::imshow("ORB-SLAM3: Current Frame",toShow);
//将图像im在名称为ORB-SLAM3: Current Frame的窗口中显示
cv::waitKey(mT);
//在mT时间内等待用户按键触发,设置waitKey(0),则表示程序会无限制的等待用户的按键事件
if(menuReset) //如果显示关键帧相机位姿的窗口中reset按钮被按了,需要重置状态
{
menuShowGraph = true;
menuShowInertialGraph = true;
menuShowKeyFrames = true;
menuShowPoints = true;
menuLocalizationMode = false;
if(bLocalizationMode)
mpSystem->DeactivateLocalizationMode();
bLocalizationMode = false;
bFollow = true;
menuFollowCamera = true;
mpSystem->ResetActiveMap();
menuReset = false;
}
if(Stop())
{
while(isStopped())
{
usleep(3000);
}
}
if(CheckFinish())
break;
}
SetFinish();
}