Pangolin库:视窗、相机、视图的构建及基础图形的绘制

Pangolin是基于OpenGL开发的绘图库,提供了基础的绘图功能和许多GUI操作。

工程构建

工程结构

此处,采用Ubuntu20.04+CLion进行开发。新建工程Study,结构如下所示:

.
├── CMakeLists.txt
├── include
│   └── main.h
└── src
    ├── CMakeLists.txt
    └── main.cpp

CMake配置

其中,根目录下CMakeLists.txt文件内容如下:

# cmake version
cmake_minimum_required(VERSION 3.21)
# project name
project(Study)
# cpp version
set(CMAKE_CXX_STANDARD 14)
# eigen
include_directories("/usr/include/eigen3")
# Sophus
find_package(Sophus REQUIRED)
include_directories(${Sophus_INCLUDE_DIRS})
# pangolin
find_package(Pangolin REQUIRED)
include_directories(${Pangolin_INCLUDE_DIRS})
# incldue
include_directories(include)
# src
add_subdirectory(src)

主要导入Eigen库、Sophas库、Pangolin库,src目录下CMakeLists.txt文件内容如下:

# exec
add_executable(Study main.cpp)
# link
target_link_libraries(Study ${Pangolin_LIBRARIES})

主要用于生成可执行二进制文件并链接Pangolin的动态库文件。

头文件

include目录用于存放头文件main.h

#ifndef STUDY_MAIN_H
#define STUDY_MAIN_H

#include <iostream>
#include <cmath>
#include <unistd.h>
//  Eigen
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Geometry>
//  Sophus
#include <sophus/so3.hpp>
#include <sophus/se3.hpp>
//  Pangolin
#include <pangolin/pangolin.h>
//  namespace
using namespace std;
using namespace Eigen;


#endif //STUDY_MAIN_H

源码

src目录用于存放源文件main.cpp:

#include <iostream>
#include "main.h"


int main() {
    cout << "Hello World" << endl;
    return 0;
}

构建Pangolin相机

在进行绘制具体内容前,首先需要学习如何构建视窗对象、观察相机、交互视图内容

视窗

pangolin::CreateWindowAndBind(std::string window_title, int w = 640, int h = 480, const Params& params = Params())
  • window_title:GUI窗口名
  • w:宽度
  • h:高度

该函数用于创建一个指定大小、名称的GUI窗口。

开启深度测试

深度测试可以使得Pangolin构建的相机只展示镜头朝向一侧的像素信息,从而避免容易混淆的透视关系。

在3D可视化中应开启深度测试,可用如下语句进行开启:

glEnable(GL_DEPTH_TEST);

如果需要关闭,可使用如下语句:

glDisable(GL_DEPTH_TEST);

相机

应注意,此处构建的相机为用于观测的相机,而非SLAM中的相机传感器。

构建观察相机对象使用如下语句进行:

pangolin::OpenGlRenderState s_cam(const OpenGlMatrix& projection_matrix, const OpenGlMatrix& modelview_matrix)
  • projection_matrix:用于构建观察相机的内参系数
  • modelview_matrix:用于构建观察相机及其视点的初始位置

其中,相机参数projection_matrix对象构建如下:

OpenGlMatrixSpec ProjectionMatrix(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
  • w、h:相机的视野宽、高
  • fu、fv、u0、v0相机的内参,对应《视觉SLAM十四讲》中内参矩阵的fx、fy、cx、cy
  • zNear、zFar:相机的最近、最远视距

而相机、视点初始坐标 modelview_matrix对象构建如下:

OpenGlMatrix ModelViewLookAt(GLprecision x, GLprecision y, GLprecision z, GLprecision lx, GLprecision ly, GLprecision lz, AxisDirection up);
  • x、y、z:相机的初始坐标
  • lx、ly、lz:相机视点的初始位置,也即相机光轴朝向
  • up:相机自身那一轴朝上放置,可选如下参数填写:
    • pangolin::AxisX:X轴正方向
    • pangolin::AxisY:Y轴正方向
    • pangolin::AxisZ:Z轴正方向
    • pangolin::AxisNegX:X轴负方向
    • pangolin::AxisNegY:Y轴负方向
    • pangolin::AxisNegZ:Z轴负方向

交互视图

交互视图(View)用于显示相机观察到的信息内容,首先需要构建相机视图的句柄:

pangolin::Handler3D handler(s_cam);

括号内参数填写相机对象,随后使用如下方式构建交互视图对象:

pangolin::View& d_cam=pangolin::CreateDisplay()
            .SetBounds(Attach bottom, Attach top, Attach left, Attach right, double aspect)
            .SetHandler(Handler* handler);
  • SetBounds():用于确定视图属性,其内参数如下:
    • bottom、top:视图在视窗内的上下范围,依次为下、上,采用相对坐标表示(0:最下侧,1:最上侧)
    • left、right:视图在视窗内的左右范围,依次为左、右,采用相对左边表示(0:最左侧,1:最右侧)
    • aspect:视图的分辨率,也即分辨率
      • 参数aspect取正值,将由前四个参数设置的视图大小来裁剪达到设置的分辨率
      • 参数aspect取负值,将拉伸图像以充满由前四个参数设置的视图范围
  • SetHandler():用于确定视图的相机句柄

清理缓存区

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

用于清空色彩缓冲区和深度缓冲区,刷新显示信息。若不使用清理,视窗将自动保留上一帧信息。

相机激活

d_cam.Activate(const OpenGlRenderState& state )

对交互视图对象进行激活相机

视窗刷新

一般,将构建一个循环用于检测视窗是否被关闭,若未关闭,将进行绘制并循环更迭。

循环条件:视窗未被关闭

!pangolin::ShouldQuit()

绘制一帧完成后,刷新视窗进行下一帧:

pangolin::FinishFrame();

综合

由此,我们就创建了一个完整的Pangolin相机对象:

#include <iostream>
#include "main.h"


int main(int argc,char **argv)
{
    //  创建视窗对象      名称:Viewer,大小:640×480
    pangolin::CreateWindowAndBind("Viewer",640,480);
    //  开启深度测试
    glEnable(GL_DEPTH_TEST);

    //  构建相机对象
    pangolin::OpenGlRenderState s_cam(
            //  相机参数
            pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100),
            //  相机、视点初始位置
            pangolin::ModelViewLookAt(-2,2,-2,0,0,0,pangolin::AxisY)
    );
    //  构建交互视图对象
    pangolin::Handler3D handler(s_cam);//   句柄
    pangolin::View& d_cam=pangolin::CreateDisplay()
            .SetBounds(0.0,1,0,1,-640.0f/480.0f)
            .SetHandler(&handler);

    //  检测视窗是否关闭
    while(!pangolin::ShouldQuit())
    {
        //  清空颜色、深度信息缓存,刷新显示信息
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        //  激活相机、交互试图
        d_cam.Activate(s_cam);
        
        /*--------  绘图  --------*/
        
        //  帧循环,推进信息更迭
        pangolin::FinishFrame();
    }
    return 0;
}

效果如下:

在这里插入图片描述

此时,点击关闭视窗,程序将自动停止。

绘制基本图形

完成在激活相机后,即可进行进一步的绘制对象。

背景色设置

使用如下语句设置背景颜色,默认为黑色:

glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
  • red、green、blue:颜色RGB数值,范围0~1
  • alpha:透明度

例如,设置红色背景:

在这里插入图片描述

绘制立方体

使用如下语句,在原点构建一个立方体对象:

pangolin::glDrawColouredCube();

效果如下:

在这里插入图片描述

绘制点

使用如下方式,绘制点:

/*--------  绘图  --------*/
//  设置点大小
glPointSize(30.0);
//  开始画点
glBegin ( GL_POINTS );
//  设置点颜色,rgb值,float类型
glColor3f(0, 1, 0);
//  设置点1坐标,3维float类型
glVertex3f(0, 0, 0);
//  设置点2颜色、坐标
glColor3f(1, 0, 0);
glVertex3f(0, 1, 0);
//  结束画点
glEnd();

效果如下:

在这里插入图片描述

绘制线段

使用如下语句,实现绘制线段:

/*--------  绘图  --------*/
//  设置大小
glLineWidth(4);
//  开始
glBegin ( GL_LINES );
//  设置颜色
glColor3f(0, 1, 0);
//  设置起点、终点坐标
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
//  结束
glEnd();

效果如下:
在这里插入图片描述

绘制折线

使用如下语句,实现绘制折线:

/*--------  绘图  --------*/
//  设置大小
glLineWidth(2);
//  开始
glBegin ( GL_LINE_STRIP );
//  设置颜色
glColor3f(0, 1, 0);
//  设置折点坐标
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glVertex3f(1, 1, 0);
//  结束
glEnd();

效果如下:
在这里插入图片描述

绘制不规则图形

使用如下语句,实现绘制封闭不规则图像:

/*--------  绘图  --------*/
//  设置大小
glLineWidth(2);
//  开始
glBegin ( GL_LINE_LOOP );
//  设置颜色
glColor3f(0, 1, 0);
//  设置折点坐标
glVertex3f(0, 0, 0);
glVertex3f(0, 1, 0);
glVertex3f(1, 1, 0);
//  结束
glEnd();

效果如下:

在这里插入图片描述

保存图像

对图像进行保持,采用如下语句进行:

pangolin::SaveWindowOnRender(const std::string& filename_hint);

图像将以filename_hint为名称进行保存在运行目录下,文件后缀名为.png

  • 18
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值