栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Windows系统下采用Visual Studio + QT + OpenGL实现RVIZ显示平面网格、坐标系和三维激光点云等功能(四)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Windows系统下采用Visual Studio + QT + OpenGL实现RVIZ显示平面网格、坐标系和三维激光点云等功能(四)

一、实现内容:

本篇文章将介绍采用Visual Studio2019 + Qt +OpenGL在Qt窗口中利用OpenGL Widget组件实现三维激光点云的显示。

二、前期基础:

本文所述内容的实现,建立在上一篇博客文章的基础上,上一篇博客的链接地址:

Windows系统下采用Visual Studio + QT + OpenGL实现RVIZ显示平面网格、坐标系和三维激光点云等功能(三)

三、实现原理:

3.1、加载点云数据文件

激光点云由一系列的三维坐标点组成,常见的点云格式有pcd、ply、las等,pcd格式的点云文件需要借助PCL点云库进行读取,Windows下配置PCL点云库较为麻烦,因此可先将pcd点云文件在Ubuntu系统下转换成csv文件,然后在Qt中直接读取csv文件。本文将采用该思路进行点云数据文件的加载,其中加载点云的数据格式为(x,y,z,intensity),其它点云格式只需简单修改下也可适用,加载csv点云核心代码如下所示:

csv点云文件读取:

#ifndef READ_DATA_H
#define READ_DATA_H

#include 
#include 

#include 
#include 
#include 

class readData
{
public:
    std::vector read_csv_data(QString docPath)
    {
        std::vector vertexs_data;
		
        QFile inputFile(docPath);

		if (inputFile.open(QIODevice::ReadOnly))
		{
            uchar* fpr = inputFile.map(0, inputFile.size());

            int subcnt = 0;
            char* substr;
            char* s = strdup((char*)fpr);

            while (substr = strsep(&s, "n"))
            {
                subcnt = 0;
                char* lineSubStr;

                while (subcnt < 4) //用来设置点云数据格式,默认(x,y,z,intensity)
                {
                    lineSubStr = strsep(&substr, ",");
                    vertexs_data.push_back(atof(lineSubStr));
                    ++subcnt;
                }
            }

			inputFile.close();
		}

		else
		{
			qDebug() << "Can't open the file!" << endl;
		}

		return vertexs_data;
	}

    char* strsep(char** stringp, const char* delim)
    {
        char* s;
        const char* spanp;
        int c, sc;
        char* tok;
        if ((s = *stringp) == NULL)
            return (NULL);
        for (tok = s;;) {
            c = *s++;
            spanp = delim;
            do {
                if ((sc = *spanp++) == c) {
                    if (c == 0)
                        s = NULL;
                    else
                        s[-1] = 0;
                    *stringp = s;
                    return (tok);
                }
            } while (sc != 0);
        }
        
    }
};
#endif

该代码可以快速读取大量点云数据,将csv中的数据存储到c++的vector中去,最终返回一个vector数据。

3.2、OpenGL中三维点云显示

三维点云实质上就是由大量的三维坐标点组成,因此在OpenGL中显示点云只需将实际点云文件中的三维坐标点传输给OpenGL,并将OpenGL图元类型设置为GL_POINTS,便可实现三维点云的显示,实现部分代码如下所示:

OpenGL中点云显示核心代码:

unsigned int opengl_widget::draw_pointdata(std::vector& point_vertexs)
{
    unsigned point_count = 0;

    glGenVertexArrays(1, &VAO_Point);
    glGenBuffers(1, &VBO_Point);

    glBindVertexArray(VAO_Point);

    glBindBuffer(GL_ARRAY_BUFFER, VBO_Point);
    glBufferData(GL_ARRAY_BUFFER, point_vertexs.size() * sizeof(float), &point_vertexs[0], GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);

    point_count = point_vertexs.size() / 4;

    return point_count;
}

shaderProgram_point.bind();
glBindVertexArray(VAO_Point);
glPointSize(1.0f);
glDrawArrays(GL_POINTS, 0, point_count);

四、效果展示:

OpenGL中点云显示效果图

五、总结:

Windows系统下采用Visual Studio + QT + OpenGL实现RVIZ显示平面网格、坐标系和三维激光点云等功能系列博客到此最终完结,代码也完全开源出来,希望最终能够帮助到大家,相互学习、共同进步。

Gitee开源代码网址:https://gitee.com/wccworld/learn_qt_opengl

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/921006.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号