程序示例精选
VS+Qt+C++点云PCL三维显示编辑系统
如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!
前言
这篇博客针对《VS+Qt+C++点云PCL三维显示编辑系统》编写代码,代码整洁,规则,易读。 学习与应用推荐首选。
文章目录
一、所需工具软件
二、使用步骤
1. 主要代码
2. 运行结果
三、在线协助
一、所需工具软件
1. VS2019,Qt
2. C++
二、使用步骤
代码如下(示例):
#include "PointCloudVision.h"
#include <QFileDialog>
#include <QFile>
#include <QMessageBox>
#include <QColorDialog>
PointCloudVision::PointCloudVision(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//初始化
init();
}
//获取两个点平行于坐标轴的最短距离
double getMinValue(PointT p1, PointT p2);
//获取两个点平行于坐标轴的最长距离
double getMaxValue(PointT p1, PointT p2);
//初始化
void PointCloudVision::init()
{
//点云初始化
m_currentCloud.reset(new PointCloudT);
//可视化对象初始化
viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
viewer->addPointCloud(m_currentCloud, "cloud");
//设置VTK可视化窗口指针
ui.qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
//设置窗口交互,窗口可接受键盘等事件
viewer->setupInteractor(ui.qvtkWidget->GetInteractor(), ui.qvtkWidget->GetRenderWindow());
//添加坐标轴
viewer->addCoordinateSystem();
//ui.qvtkWidget->update();
//槽函数
connect(&heightRampDlg, SIGNAL(setHeightRamp(int, double)), this, SLOT(setHeightRamp(int, double)));
}
//打开点云
void PointCloudVision::on_action_open_triggered()
{
init();
QString fileName = QFileDialog::getOpenFileName(this, "Open PointCloud", ".", "Open PCD files(*.pcd)");
if (!fileName.isEmpty())
{
std::string file_name = fileName.toStdString();
pcl::PCLPointCloud2 cloud2;
Eigen::Vector4f origin;
Eigen::Quaternionf orientation;
int pcd_version;
int data_type;
unsigned int data_idx;
int offset = 0;
pcl::PCDReader rd;
rd.readHeader(file_name, cloud2, origin, orientation, pcd_version, data_type, data_idx);
if (data_type == 0)
{
pcl::io::loadPCDFile(fileName.toStdString(), *m_currentCloud);
}
else if (data_type == 2)
{
pcl::PCDReader reader;
reader.read<pcl::PointXYZ>(fileName.toStdString(), *m_currentCloud);
}
viewer->addCoordinateSystem();
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");
viewer->updatePointCloud(m_currentCloud, "cloud");
// 获取点云数据的最小和最大坐标值
pcl::getMinMax3D(*m_currentCloud, p_min, p_max);
viewer->resetCamera();
ui.qvtkWidget->update();
}
}
//重设视角
void PointCloudVision::on_action_reset_triggered()
{
if (!m_currentCloud->empty())
{
viewer->resetCamera();
ui.qvtkWidget->update();
}
}
//俯视图
void PointCloudVision::on_action_up_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(0.5 * (p_min.x + p_max.x), 0.5 * (p_min.y + p_max.y), p_max.z + 2 * maxLen, 0.5 * (p_min.x + p_max.x), 0.5 * (p_min.y + p_max.y), 0, 0, 1, 0);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//前视图
void PointCloudVision::on_action_front_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(0.5 * (p_min.x + p_max.x), p_min.y - 2 * maxLen, 0.5 * (p_min.z + p_max.z), 0.5 * (p_min.x + p_max.x), 0, 0.5 * (p_min.z + p_max.z), 0, 0, 1);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//左视图
void PointCloudVision::on_action_left_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(p_min.x - 2 * maxLen, 0.5 * (p_min.y + p_max.y), 0.5 * (p_min.z + p_max.z), 0, 0.5 * (p_min.y + p_max.y), 0.5 * (p_min.z + p_max.z), 0, 0, 1);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//后视图
void PointCloudVision::on_action_back_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(0.5 * (p_min.x + p_max.x), p_max.y + 2 * maxLen, 0.5 * (p_min.z + p_max.z), 0.5 * (p_min.x + p_max.x), 0, 0.5 * (p_min.z + p_max.z), 0, 0, 1);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//右视图
void PointCloudVision::on_action_right_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(p_max.x + 2 * maxLen, 0.5 * (p_min.y + p_max.y), 0.5 * (p_min.z + p_max.z), 0, 0.5 * (p_min.y + p_max.y), 0.5 * (p_min.z + p_max.z), 0, 0, 1);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//底视图
void PointCloudVision::on_action_bottom_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(0.5 * (p_min.x + p_max.x), 0.5 * (p_min.y + p_max.y), p_min.z - 2 * maxLen, 0.5 * (p_min.x + p_max.x), 0.5 * (p_min.y + p_max.y), 0, 0, 1, 0);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//前轴测
void PointCloudVision::on_action_frontIso_triggered()
{
if (!m_currentCloud->empty())
{
viewer->setCameraPosition(p_min.x - 2 * maxLen, p_min.y - 2 * maxLen, p_max.z + 2 * maxLen, 0.5 * (p_min.x + p_max.x), 0.5 * (p_min.y + p_max.y), 0.5 * (p_min.z + p_max.z), 1, 1, 0);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
}
//后轴测
void PointCloudVision::on_action_backIso_triggered()
{
viewer->setCameraPosition(p_max.x + 2 * maxLen, p_max.y + 2 * maxLen, p_max.z + 2 * maxLen, 0.5 * (p_min.x + p_max.x), 0.5 * (p_min.y + p_max.y), 0.5 * (p_min.z + p_max.z), -1, -1, 0);
viewer->updatePointCloud(m_currentCloud, "cloud");
ui.qvtkWidget->update();
on_action_reset_triggered();
}
//设置点云颜色
void PointCloudVision::on_action_setColor_triggered()
{
QColor color = QColorDialog::getColor(Qt::white, this, "设置点云颜色", QColorDialog::ShowAlphaChannel);
viewer->removeAllPointClouds();
pcl::visualization::PointCloudColorHandlerCustom<PointT> singleColor(m_currentCloud, color.red(), color.green(), color.blue());
viewer->addPointCloud(m_currentCloud, singleColor, "myCloud", 0);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY, color.alpha() * 1.0 / 255, "myCloud");
ui.qvtkWidget->update();
}
//设置高度渲染
void PointCloudVision::on_action_heightRamp_triggered()
{
heightRampDlg.show();
}
//进行高度渲染
void PointCloudVision::setHeightRamp(int dir, double height)
{
//清空点云
viewer->removeAllPointClouds();
m_heightCloudList.clear();
double min_range = 0;
double max_range = 0;
std::string field = "x";
switch (dir)
{
case 0:
min_range = p_min.x;
max_range = p_max.x;
field = "x";
break;
case 1:
min_range = p_min.y;
max_range = p_max.y;
field = "y";
break;
case 2:
min_range = p_min.z;
max_range = p_max.z;
field = "z";
break;
default:
break;
}
for (double i = min_range - 1; i < max_range + height;)
{
PointCloudT::Ptr cloudTemp(new PointCloudT());
pcl::PassThrough<PointT> pass; //直通滤波器对象
pass.setInputCloud(m_currentCloud); //输入点云
pass.setFilterFieldName(field); //设置过滤字段
pass.setFilterLimits(i, i + height); //设置过滤范围
pass.setFilterLimitsNegative(false); //设置保留字段
pass.filter(*cloudTemp); //执行滤波
i += height;
m_heightCloudList.append(cloudTemp);
}
//分段渲染
for (int j = 0; j < m_heightCloudList.size(); j++)
{
pcl::visualization::PointCloudColorHandlerGenericField<PointT> fieldColor(m_heightCloudList.at(j), field);
std::string index = std::to_string(j);
viewer->addPointCloud(m_heightCloudList.at(j), fieldColor, index);
}
}
double getMinValue(PointT p1, PointT p2)
{
double min = 0;
if (p1.x - p2.x > p1.y - p2.y)
{
min = p1.y - p2.y;
}
else
{
min = p1.x - p2.x;
}
if (min > p1.z - p2.z)
{
min = p1.z - p2.z;
}
return min;
}
double getMaxValue(PointT p1, PointT p2)
{
double max = 0;
if (p1.x - p2.x > p1.y - p2.y)
{
max = p1.x - p2.x;
}
else
{
max = p1.y - p2.y;
}
if (max < p1.z - p2.z)
{
max = p1.z - p2.z;
}
return max;
}
运行结果
三、在线协助:
如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Visual Studio, Qt, C++, Python编程语言入门指导
3)界面美化
4)软件制作
5)云服务器申请
6)网站制作
当前文章连接:https://blog.csdn.net/alicema1111/article/details/132666851
个人博客主页:https://blog.csdn.net/alicema1111?type=blog
博主所有文章点这里:https://blog.csdn.net/alicema1111?type=blog
博主推荐:
Python人脸识别考勤打卡系统:
https://blog.csdn.net/alicema1111/article/details/133434445
Python果树水果识别:https://blog.csdn.net/alicema1111/article/details/130862842
Python+Yolov8+Deepsort入口人流量统计:https://blog.csdn.net/alicema1111/article/details/130454430
Python+Qt人脸识别门禁管理系统:https://blog.csdn.net/alicema1111/article/details/130353433
Python+Qt指纹录入识别考勤系统:https://blog.csdn.net/alicema1111/article/details/129338432
Python Yolov5火焰烟雾识别源码分享:https://blog.csdn.net/alicema1111/article/details/128420453
Python+Yolov8路面桥梁墙体裂缝识别:https://blog.csdn.net/alicema1111/article/details/133434445
Python+Yolov5道路障碍物识别:https://blog.csdn.net/alicema1111/article/details/129589741
Python+Yolov5跌倒检测 摔倒检测 人物目标行为 人体特征识别:https://blog.csdn.net/alicema1111/article/details/129272048