PCL点云处理:最小生成树修剪和可视化
以下代码使用PCL库对点云进行最小生成树修剪,并使用可视化工具显示结果。代码展示如何根据节点连接度和权重来移除最小生成树中的特定边,并用不同颜色标记关键节点。
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
// 定义最小生成树的边结构
struct Edge
{
int src;
int tgt;
float weight;
};
// 假设已获得点云数据 `cloud` 和最小生成树结果 `result`
// ...
// 创建一个新的点云对象保存修剪后的最小生成树结果
pcl::PointCloud<pcl::PointXYZ>::Ptr new_cloud(new pcl::PointCloud<pcl::PointXYZ>);
new_cloud->width = cloud->width;
new_cloud->height = cloud->height;
new_cloud->points.resize(cloud->points.size());
// 找到在最小生成树中出现三次的节点
std::unordered_map<int, int> node_count;
for (const auto& edge : result)
{
node_count[edge.src]++;
node_count[edge.tgt]++;
}
std::vector<int> threejiedian;
for (const auto& pair : node_count)
{
if (pair.second == 3)
{
threejiedian.push_back(pair.first);
}
}
// 如果与threejiedian相连的边的权重小于0.0008,则从最小生成树中移除该边
std::vector<Edge> pruned_result;
for (const auto& edge : result)
{
if (std::find(threejiedian.begin(), threejiedian.end(), edge.src) != threejiedian.end() ||
std::find(threejiedian.begin(), threejiedian.end(), edge.tgt) != threejiedian.end())
{
if (edge.weight <= 0.008)
{
pruned_result.push_back(edge);
}
}
else
{
pruned_result.push_back(edge);
}
}
// 将修剪后的最小生成树的顶点添加到新的点云对象中
for (const auto& edge : pruned_result)
{
const auto& src_point = cloud->points[edge.src];
const auto& tgt_point = cloud->points[edge.tgt];
new_cloud->points[edge.src] = src_point;
new_cloud->points[edge.tgt] = tgt_point;
}
// 将与threejiedian相连的边的顶点设置为绿色
pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
colored_cloud->points.resize(cloud->points.size());
for (const auto& edge : result)
{
if (std::find(threejiedian.begin(), threejiedian.end(), edge.src) != threejiedian.end() ||
std::find(threejiedian.begin(), threejiedian.end(), edge.tgt) != threejiedian.end())
{
colored_cloud->points[edge.src].r = 0;
colored_cloud->points[edge.src].g = 255;
colored_cloud->points[edge.src].b = 0;
colored_cloud->points[edge.tgt].r = 0;
colored_cloud->points[edge.tgt].g = 255;
colored_cloud->points[edge.tgt].b = 0;
}
}
// 将y值最大的threejiedian节点用绿色小球显示
int max_y_index = -1;
float max_y = std::numeric_limits<float>::min();
for (const auto& index : threejiedian)
{
const auto& point = cloud->points[index];
if (point.y > max_y)
{
max_y = point.y;
max_y_index = index;
}
}
colored_cloud->points[max_y_index].r = 0;
colored_cloud->points[max_y_index].g = 255;
colored_cloud->points[max_y_index].b = 0;
// 将最小生成树中出现一次的节点设置为红色
std::unordered_map<int, int> node_count;
for (const auto& edge : result)
{
node_count[edge.src]++;
node_count[edge.tgt]++;
}
for (const auto& pair : node_count)
{
if (pair.second == 1)
{
colored_cloud->points[pair.first].r = 255;
colored_cloud->points[pair.first].g = 0;
colored_cloud->points[pair.first].b = 0;
}
}
// 创建可视化对象
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer('Point Cloud Viewer'));
// 添加原始点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 255, 255);
viewer->addPointCloud(cloud, cloud_color_handler, 'cloud');
// 添加修剪后的最小生成树点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> new_cloud_color_handler(new_cloud, 0, 0, 255);
viewer->addPointCloud(new_cloud, new_cloud_color_handler, 'new_cloud');
// 添加标记的节点
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> colored_cloud_color_handler(colored_cloud, 'rgb');
viewer->addPointCloud(colored_cloud, colored_cloud_color_handler, 'colored_cloud');
// 设置点云渲染参数
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, 'cloud');
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, 'new_cloud');
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, 'colored_cloud');
// 显示点云
viewer->spin();
这段代码展示了如何使用PCL库对点云进行最小生成树修剪,并使用可视化工具显示结果。代码首先定义了最小生成树的边结构,然后根据节点连接度和权重来移除最小生成树中的特定边。最后,代码使用不同的颜色来标记关键节点,并使用可视化工具将结果显示出来。
需要注意的是,这段代码需要先获得点云数据和最小生成树结果,代码中使用了cloud和result来表示这两个变量。用户需要根据自己的实际情况来替换这两个变量。
原文地址: https://www.cveoy.top/t/topic/pVUT 著作权归作者所有。请勿转载和采集!