Pangolin库:子图

子图

实际用于SLAM点云信息的可视化时,希望能够实现同时显示相机当前图像信息以及特征点跟踪。此时就需要构建子图对象,展示点云信息的同时显示其余信息。

构建子图对象

构建子图对象如下:

pangolin::View& sub_viewer = pangolin::Display(const std::string& name)
            .SetBounds(Attach bottom, Attach top, Attach left, Attach right, double aspect)
            .SetLock(Lock horizontal, Lock vertical );
  • name:视图或子图的名称
  • SetBounds:用于设置子图的位置,同交互视图相同
  • SetLock:设置子图锁定位置,当缩放视窗时,将自动锁定子图至规定位置
    • horizontal:水平锁定位置,选填如下内容:
      • LockLeft:左侧
      • LockCenter:中央
      • LockRight:右侧
    • vertical:垂直锁定位置,选填如下内容:
      • LockBottom:底部
      • LockCenter:中央
      • LockTop:顶部

图像容器

对于子图要展示的图像内容,应先创建容器用于装载:

pangolin::GlTexture imgTexture(GLint width, GLint height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data )
  • width、height:装载的图像宽度、高度,同被装载的图像宽度、高度一致
  • internal_format:Pangolin内部图像存储格式,一般默认填写GL_RGB
  • sampling_linear:是否开启现行采样,默认填写false
  • border:边界大小(像素),默认填写0
  • glformat:GL图像存储格式,一般采用OpenCV进行读取图像,故而填写GL_BGR
  • gltype:GL图像数据格式,OpenCV中格式为UInt类型,故而填写GL_UNSIGNED_BYTE
  • data:GL图像数据

装载图像

将图像信息装载至容器

imgTexture.Upload(const void* data, GLenum data_format, GLenum data_type)
  • data:图像数据
  • data_format:图像存储格式
  • data_type:图像数据格式

显示子图

最后,显示子图信息

//  激活子图
sub_viewer.Activate();
//  子图背景色设置
glColor3f(1.0f, 1.0f, 1.0f);
//  反转Y轴,否则输出是倒着的
imgTexture.RenderToViewportFlipY();

此处,由于视图原点位置左下角,而OpenCV原点位于左上角,故而需要反转Y轴。

综合:子图显示

综上所述,构建子图的全体流程如下:

CMake

由于使用了OpenCV库,需要引入CV库:

根目录下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})
# opencv
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
# incldue
include_directories(include)
# src
add_subdirectory(src)

src下CMakeLists.txt文件如下:

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

头文件

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>
//  OpenCV
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

//  namespace
using namespace std;
using namespace Eigen;


#endif //STUDY_MAIN_H

源代码

src下源文件main.cpp如下:

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

int main()
{
    /*--------  Pangolin相机    --------*/
    //  视窗
    pangolin::CreateWindowAndBind("MultiImage", 752, 480);
    //  启动深度测试
    glEnable(GL_DEPTH_TEST);
    //  相机
    pangolin::OpenGlRenderState s_cam(
            pangolin::ProjectionMatrix(752, 480, 420, 420, 320, 320, 0.1, 1000),
            pangolin::ModelViewLookAt(-2, 0, -2, 0, 0, 0, pangolin::AxisY)
    );
    /*--------  视图、子图   --------*/
    //  主视图cam,拉伸
    pangolin::View& d_cam = pangolin::Display("cam")
            .SetBounds(0., 1., 0., 1., -752/480.)
            .SetHandler(new pangolin::Handler3D(s_cam));
    //  子图1 image_1,裁剪,锁定左上角
    pangolin::View& cv_img_1 = pangolin::Display("image_1")
            .SetBounds(2/3.0f, 1.0f, 0., 1/3.0f, 752/480.)
            .SetLock(pangolin::LockLeft, pangolin::LockTop);
    //  子图2 image_2,裁剪,锁定右下角
    pangolin::View& cv_img_2 = pangolin::Display("image_2")
            .SetBounds(0., 1/3.0f, 2/3.0f, 1.0, 752/480.)
            .SetLock(pangolin::LockRight, pangolin::LockBottom);

    // glTexture容器,用于读取图像
    pangolin::GlTexture imgTexture1(752, 480, GL_RGB, false, 0, GL_BGR, GL_UNSIGNED_BYTE);
    pangolin::GlTexture imgTexture2(752, 480, GL_RGB, false, 0, GL_BGR, GL_UNSIGNED_BYTE);

    while(!pangolin::ShouldQuit()){
        //  清空颜色、深度缓存区
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //  背景色
        glClearColor(0.2, 0.2, 0.2, 0.3);
        //  激活相机
        d_cam.Activate(s_cam);

        /*--------    绘制主视图内容   --------*/
        //  原点立方体
        glColor3f(1.0f, 1.0f, 1.0f);
        pangolin::glDrawColouredCube();

        /*--------  子图信息    --------*/
        //  读取图像
        cv::Mat img1 = cv::imread("/home/jasonli/workspace/Study/pic/01.png");
        cv::Mat img2 = cv::imread("/home/jasonli/workspace/Study/pic/02.png");
        //  装载图像
        imgTexture1.Upload(img1.data, GL_BGR, GL_UNSIGNED_BYTE);
        imgTexture2.Upload(img2.data, GL_BGR, GL_UNSIGNED_BYTE);

        /*--------  子图1配置   --------*/
        //  激活子图1
        cv_img_1.Activate();
        //  子图1背景色设置
        glColor3f(1.0f, 1.0f, 1.0f);
        //  反转Y轴,否则输出是倒着的
        imgTexture1.RenderToViewportFlipY();

        /*--------  子图2配置   --------*/
        //  激活子图2
        cv_img_2.Activate();
        //  子图1背景色设置
        glColor3f(1.0f, 1.0f, 1.0f);
        //  反转Y轴,否则输出是倒着的
        imgTexture2.RenderToViewportFlipY();

        //  帧循环
        pangolin::FinishFrame();
    }

    return 0;
}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值