一、实现内容:
本篇文章将介绍采用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



