当前位置: 首页 > news >正文

QT6.5.3 vs2022 pcl1.14.1窗体界面打开pcd点云文件

vs2022结合qt6.5.3+pcl1.14.1打开pcd文件的一个例子

提前条件:已经安装vs2022,pcl1.14.1,qt6.5.3,并且已经配置pcl属性表,其中vtk是需要编译的

Pcl1.14.1对应的是VTK9.3,编译vtk的时候要选择With_QT

vs2022中安装qt插件

设置qt路径

设置此属性为true

实例开始:打开vs2022选择QtWidgetsApplication

项目名字自定义

下一步点Finish

双击UI文件

出来设计界面后,添加一个按钮pushButton_open,设置如下图

拖动一个openGLWidget到窗体上

右键点击openGLWidget选择提升为...

提升的类名称填:QVTKOpenGLNativeWidget,下面会自动填,然后点添加

全局包含打勾,再点提升

再添加一个进度条控件,保存并闭设计窗口

回到Visual Studio中右键点击UI文件--编译(UI中修改后都需要编译)

此时运行,可能会出现以下错误

无法打开包括文件: “QOpenGLWidget”: No such file or directory QtWidgetsPcd

添加如下图位置的内容

重新生成

给打开按钮添加槽(事件)

添加:pushButton_openClicked()

保存后,编译

在QtWidgetsPcd.h文件中添加以下代码

#pragma once
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
    //点云数据存储pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;//初始化vtk部件void initialVtkWidget();private slots:void pushButton_OpenClicked(); //打开pcd文件的按钮

再修改QtWidgetsPcd.cpp文件

以下是修改前的截图

修改后的代码:

#include "QtWidgetsPcd.h"#include <QFileDialog>
#include <iostream>
#include <vtkRenderWindow.h>
#include <QColorDialog>
#include "vtkGenericOpenGLRenderWindow.h"
#include "QVTKOpenGLNativeWidget.h"
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/io/ply_io.h>
#pragma execution_character_set("utf-8")QtWidgetsPcd::QtWidgetsPcd(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);initialVtkWidget();ui.progressBar->setValue(0); // 初始化进度条}QtWidgetsPcd::~QtWidgetsPcd()
{}void QtWidgetsPcd::initialVtkWidget()
{cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);auto renderer2 = vtkSmartPointer<vtkRenderer>::New();auto renderWindow2 = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow2->AddRenderer(renderer2);cloud->resize(1);viewer.reset(new pcl::visualization::PCLVisualizer(renderer2, renderWindow2, "viewer", false));viewer->addPointCloud(cloud, "cloud");// 添加坐标轴线条double lineWidth = 0.8; // 坐标轴粗细viewer->addLine<pcl::PointXYZ>(pcl::PointXYZ(0, 0, 0), pcl::PointXYZ(1, 0, 0), 1.0, 0.0, 0.0, "x_axis", lineWidth);viewer->addLine<pcl::PointXYZ>(pcl::PointXYZ(0, 0, 0), pcl::PointXYZ(0, 1, 0), 0.0, 1.0, 0.0, "y_axis", lineWidth);viewer->addLine<pcl::PointXYZ>(pcl::PointXYZ(0, 0, 0), pcl::PointXYZ(0, 0, 1), 0.0, 0.0, 1.0, "z_axis", lineWidth);//添加X, Y, Z标注viewer->addText3D("X", pcl::PointXYZ(1.1, 0, 0), 0.1, 1.0, 0.0, 0.0, "x_text");viewer->addText3D("Y", pcl::PointXYZ(0, 1.1, 0), 0.1, 0.0, 1.0, 0.0, "y_text");viewer->addText3D("Z", pcl::PointXYZ(0, 0, 1.1), 0.1, 0.0, 0.0, 1.0, "z_text");ui.openGLWidget->setRenderWindow(viewer->getRenderWindow());viewer->setupInteractor(ui.openGLWidget->interactor(), ui.openGLWidget->renderWindow());ui.openGLWidget->update();viewer->setBackgroundColor(0, 0, 0);
}void QtWidgetsPcd::pushButton_openClicked()
{QString fileName = QFileDialog::getOpenFileName(this,tr("Open PointCloud"), ".",tr("Point Cloud Files (*.pcd *.ply *.stl)"));if (!fileName.isEmpty()){ui.progressBar->setValue(0); // 重置进度条QtConcurrent::run([this, fileName]() {std::string file_name = fileName.toStdString();std::string file_extension = file_name.substr(file_name.find_last_of('.') + 1);if (file_extension == "pcd"){pcl::PCDReader reader;reader.read(file_name, *cloud);// 模拟解析过程中的进度更新for (int i = 0; i < 100; i++){QThread::msleep(10); // 模拟处理延时QMetaObject::invokeMethod(this, [this, i]() {ui.progressBar->setValue(i + 1);}, Qt::QueuedConnection);}}else if (file_extension == "ply"){pcl::io::loadPLYFile(file_name, *cloud);// 模拟解析过程中的进度更新for (int i = 0; i < 100; i++){QThread::msleep(10); // 模拟处理延时QMetaObject::invokeMethod(this, [this, i]() {ui.progressBar->setValue(i + 1);}, Qt::QueuedConnection);}}else if (file_extension == "stl"){pcl::PolygonMesh mesh;pcl::io::loadPolygonFileSTL(file_name, mesh);pcl::fromPCLPointCloud2(mesh.cloud, *cloud);// 模拟解析过程中的进度更新for (int i = 0; i < 100; i++){QThread::msleep(10); // 模拟处理延时QMetaObject::invokeMethod(this, [this, i]() {ui.progressBar->setValue(i + 1);}, Qt::QueuedConnection);}}QMetaObject::invokeMethod(this, [this]() {viewer->updatePointCloud(cloud, "cloud");viewer->resetCamera();viewer->getRenderWindow()->Render(); // 强制渲染viewer->setCameraPosition(0, 0, 1,   // 相机位置 (Z轴正方向朝屏幕)0, 0, 0,   // 目标点 (原点)0, 1, 0    // 垂直方向 (Y轴垂直向上));viewer->resetCamera();ui.openGLWidget->update();}, Qt::QueuedConnection);});}
}

重新生成,并运行,可以打开一个pcd文件测试

后续:

增加一个创建点云按钮 pushButton_New1

//创建点云星云
void QtWidgetsApplication3::pushButton_New1Clicked()
{try {// 创建新的RGB点云pcl::PointCloud<pcl::PointXYZRGB>::Ptr rgb_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);// 设置点云大小rgb_cloud->width = 5000;rgb_cloud->height = 1;rgb_cloud->is_dense = false;rgb_cloud->points.resize(rgb_cloud->width * rgb_cloud->height);// 生成球面上的随机点,并为每个点设置颜色srand(static_cast<unsigned int>(time(0)));for (size_t i = 0; i < rgb_cloud->points.size(); ++i){// 生成球面坐标double theta = ((double)rand() / RAND_MAX) * 2.0 * M_PI;  // 0 到 2πdouble phi = acos(1 - 2 * ((double)rand() / RAND_MAX));   // 0 到 πdouble radius = 5.0;// 设置位置rgb_cloud->points[i].x = radius * sin(phi) * cos(theta);rgb_cloud->points[i].y = radius * sin(phi) * sin(theta);rgb_cloud->points[i].z = radius * cos(phi);// 基于位置设置渐变色// 将球面坐标映射到RGB颜色空间uint8_t r = static_cast<uint8_t>((sin(theta) + 1) * 127.5);uint8_t g = static_cast<uint8_t>((cos(phi) + 1) * 127.5);uint8_t b = static_cast<uint8_t>((cos(theta) + 1) * 127.5);// 设置点的RGB颜色rgb_cloud->points[i].r = r;rgb_cloud->points[i].g = g;rgb_cloud->points[i].b = b;}// 转换为XYZ点云以供显示pcl::copyPointCloud(*rgb_cloud, *cloud);// 移除旧的点云viewer->removePointCloud("cloud");// 使用RGB颜色处理器pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(rgb_cloud);viewer->addPointCloud<pcl::PointXYZRGB>(rgb_cloud, rgb, "cloud");// 设置点云渲染属性viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");// 设置相机位置viewer->setCameraPosition(15, 15, 15,  // 相机位置0, 0, 0,     // 目标点0, 0, 1      // 上方向);// 重置相机和更新显示viewer->resetCamera();viewer->getRenderWindow()->Render();ui.openGLWidget->update();std::cout << "彩色点云生成成功!" << std::endl;} catch (const std::exception& e) {std::cerr << "生成点云时发生错误: " << e.what() << std::endl;}
}

 

http://www.dtcms.com/a/310314.html

相关文章:

  • PAT 1022 Digital Library
  • nodejs最近开发过程中的总结
  • 【LeetCode】算法详解#11 ---相交链表
  • 智能Agent场景实战指南 Day 29:Agent市场趋势与前沿技术
  • 一篇文章读懂AI Agent(智能体)
  • spring boot 启动报错---java: 无法访问org.springframework.boot.SpringApplication 错误的类文件
  • 获取LLM 内部的结构信息和矩阵维度信息
  • LeetCode 热题100:206. 反转链表
  • 【AI问答】PromQL中interval和rate_interval的区别以及Grafana面板的配置建议
  • 从本地到云端:将Linux文件夹上传至GitHub仓库的完整指南
  • 动态爱心树
  • 商汤悟能具身智能平台让机器人「觉醒」
  • Mysql 实战问题处理速通
  • 《操作系统真象还原》 第五章 保护模式进阶
  • h5独立部署
  • Galaxea机器人由星海图人工智能科技有限公司研发的高性能仿人形机器人
  • 国内短剧CSP系统开发:技术架构与合规实践全解析
  • GESP2025年6月认证C++八级( 第三部分编程题(1)树上旅行)
  • 一体化伺服电机在自动焊接设备中的控制转台转动部分应用案例
  • 【文章素材】3dBackgroundBoxes(3D背景盒子组件)项目及文章思路
  • 【PHP 自动加载机制详解】
  • HCIA实验——2.EVE模拟器的安装【完成】
  • iOS企业签名掉签,iOS企业签名掉签了怎么办?
  • 书生浦语第五期L0G1000
  • 【算法】指数滑动滤波器
  • 算法篇----位运算
  • 基于SAMP算法OFDM系统信道估计
  • 学习笔记090——Ubuntu 中 UFW 防火墙的使用
  • 香港正式启动稳定币牌照制度!推动中国的人民币国际化?
  • 本地浏览器设置上网代理服务