#include <iostream>
#include <algorithm>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
void BoundaryExtraction(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary, int resolution)
{
pcl::PointXYZ px_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
pcl::PointXYZ px_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
float delta_x = (px_max.x - px_min.x) / resolution;
float min_y = INT_MAX, max_y = -INT_MAX;
std::vector<int> indexs_x(2 * resolution + 2);
std::vector<std::pair<float, float>> minmax_x(resolution + 1, { INT_MAX,-INT_MAX });
for (size_t i = 0; i < cloud->size(); ++i)
{
int id = (cloud->points[i].x - px_min.x) / delta_x;
if (cloud->points[i].y < minmax_x[id].first)
{
minmax_x[id].first = cloud->points[i].y;
indexs_x[id] = i;
}
else if (cloud->points[i].y > minmax_x[id].second)
{
minmax_x[id].second = cloud->points[i].y;
indexs_x[id + resolution + 1] = i;
}
}
pcl::PointXYZ py_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
pcl::PointXYZ py_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
float delta_y = (py_max.y - py_min.y) / resolution;
float min_x = INT_MAX, max_x = -INT_MAX;
std::vector<int> indexs_y(2 * resolution + 2);
std::vector<std::pair<float, float>> minmax_y(resolution + 1, { INT_MAX,-INT_MAX });
for (size_t i = 0; i < cloud->size(); ++i)
{
int id = (cloud->points[i].y - py_min.y) / delta_y;
if (cloud->points[i].x < minmax_y[id].first)
{
minmax_y[id].first = cloud->points[i].x;
indexs_y[id] = i;
}
else if (cloud->points[i].x > minmax_y[id].second)
{
minmax_y[id].second = cloud->points[i].x;
indexs_y[id + resolution + 1] = i;
}
}
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xboundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indexs_x, *cloud_xboundary);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_yboundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indexs_y, *cloud_yboundary);
*cloud_boundary = *cloud_xboundary + *cloud_yboundary;
}
int main(int argc, char* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>) ;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("F:\\19.pcd", *cloud);
BoundaryExtraction(cloud, cloud_boundary, 200);
pcl::io::savePCDFile("F:\\boundary1.pcd", *cloud_boundary);
pcl::visualization::PCLVisualizer viewer("boundary");
viewer.setBackgroundColor(0, 0, 0);//三个参数,分别代表红、绿、蓝颜色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_color(cloud_boundary->makeShared(), 128, 128, 0);//类的实例 target_color,它用于自定义点云的颜色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> result_color(cloud_boundary->makeShared(), 0, 255, 0);
viewer.addPointCloud(cloud_boundary, result_color, "result_cloud");//用于
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
}
return EXIT_SUCCESS;
}
填充边界
#include <iostream>
#include <algorithm>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
// 边界提取函数
void BoundaryExtraction(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary, int resolution) {
pcl::PointXYZ px_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
pcl::PointXYZ px_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
float delta_x = (px_max.x - px_min.x) / resolution;
std::vector<int> indexs_x(2 * resolution + 2);
std::vector<std::pair<float, float>> minmax_x(resolution + 1, { INT_MAX, -INT_MAX });
for (size_t i = 0; i < cloud->size(); ++i) {
int id = (cloud->points[i].x - px_min.x) / delta_x;
if (cloud->points[i].y < minmax_x[id].first) {
minmax_x[id].first = cloud->points[i].y;
indexs_x[id] = i;
} else if (cloud->points[i].y > minmax_x[id].second) {
minmax_x[id].second = cloud->points[i].y;
indexs_x[id + resolution + 1] = i;
}
}
pcl::PointXYZ py_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
pcl::PointXYZ py_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
float delta_y = (py_max.y - py_min.y) / resolution;
std::vector<int> indexs_y(2 * resolution + 2);
std::vector<std::pair<float, float>> minmax_y(resolution + 1, { INT_MAX, -INT_MAX });
for (size_t i = 0; i < cloud->size(); ++i) {
int id = (cloud->points[i].y - py_min.y) / delta_y;
if (cloud->points[i].x < minmax_y[id].first) {
minmax_y[id].first = cloud->points[i].x;
indexs_y[id] = i;
} else if (cloud->points[i].x > minmax_y[id].second) {
minmax_y[id].second = cloud->points[i].x;
indexs_y[id + resolution + 1] = i;
}
}
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xboundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indexs_x, *cloud_xboundary);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_yboundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indexs_y, *cloud_yboundary);
*cloud_boundary = *cloud_xboundary + *cloud_yboundary;
}
// 边界点云填充函数
void FillBoundary(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary, pcl::PointCloud<pcl::PointXYZ>::Ptr filled_boundary, float step) {
for (size_t i = 0; i < cloud_boundary->size() - 1; ++i) {
pcl::PointXYZ pt1 = cloud_boundary->points[i];
pcl::PointXYZ pt2 = cloud_boundary->points[i + 1];
filled_boundary->push_back(pt1);
// 插值生成填充点
int num_steps = std::ceil(std::sqrt(std::pow(pt2.x - pt1.x, 2) + std::pow(pt2.y - pt1.y, 2)) / step);
for (int j = 1; j <= num_steps; ++j) {
pcl::PointXYZ interpolated_pt;
interpolated_pt.x = pt1.x + j * (pt2.x - pt1.x) / num_steps;
interpolated_pt.y = pt1.y + j * (pt2.y - pt1.y) / num_steps;
interpolated_pt.z = pt1.z + j * (pt2.z - pt1.z) / num_steps;
filled_boundary->push_back(interpolated_pt);
}
}
filled_boundary->push_back(cloud_boundary->back()); // 添加最后一个边界点
}
int main(int argc, char* argv[]) {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr filled_boundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("F:\\19.pcd", *cloud);
BoundaryExtraction(cloud, cloud_boundary, 200);
// 插值填充边界
FillBoundary(cloud_boundary, filled_boundary, 0.01); // 0.01表示插值步长
pcl::io::savePCDFile("F:\\boundary1_filled.pcd", *filled_boundary);
std::cout << "边界点云已保存为 boundary1_filled.pcd" << std::endl;
// 可视化边界
pcl::visualization::PCLVisualizer viewer("boundary");
viewer.setBackgroundColor(0, 0, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_color(filled_boundary->makeShared(), 128, 128, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> result_color(filled_boundary->makeShared(), 0, 255, 0);
viewer.addPointCloud(filled_boundary, result_color, "result_cloud");
while (!viewer.wasStopped()) {
viewer.spinOnce(100);
}
return EXIT_SUCCESS;
}
ransac拟合边界直线
#include <iostream>
#include <algorithm>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
// 边界提取函数
void BoundaryExtraction(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary, int resolution) {
// (边界提取代码保持不变)
pcl::PointXYZ px_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) { return pt1.x < pt2.x; });
pcl::PointXYZ px_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) { return pt1.x < pt2.x; });
float delta_x = (px_max.x - px_min.x) / resolution;
std::vector<int> indexs_x(2 * resolution + 2);
std::vector<std::pair<float, float>> minmax_x(resolution + 1, { INT_MAX,-INT_MAX });
for (size_t i = 0; i < cloud->size(); ++i) {
int id = (cloud->points[i].x - px_min.x) / delta_x;
if (cloud->points[i].y < minmax_x[id].first) {
minmax_x[id].first = cloud->points[i].y;
indexs_x[id] = i;
}
else if (cloud->points[i].y > minmax_x[id].second) {
minmax_x[id].second = cloud->points[i].y;
indexs_x[id + resolution + 1] = i;
}
}
pcl::PointXYZ py_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) { return pt1.y < pt2.y; });
pcl::PointXYZ py_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) { return pt1.y < pt2.y; });
float delta_y = (py_max.y - py_min.y) / resolution;
std::vector<int> indexs_y(2 * resolution + 2);
std::vector<std::pair<float, float>> minmax_y(resolution + 1, { INT_MAX,-INT_MAX });
for (size_t i = 0; i < cloud->size(); ++i) {
int id = (cloud->points[i].y - py_min.y) / delta_y;
if (cloud->points[i].x < minmax_y[id].first) {
minmax_y[id].first = cloud->points[i].x;
indexs_y[id] = i;
}
else if (cloud->points[i].x > minmax_y[id].second) {
minmax_y[id].second = cloud->points[i].x;
indexs_y[id + resolution + 1] = i;
}
}
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xboundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indexs_x, *cloud_xboundary);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_yboundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloud, indexs_y, *cloud_yboundary);
*cloud_boundary = *cloud_xboundary + *cloud_yboundary;
}
// RANSAC 直线拟合函数
void FitBoundaryLines(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary) {
pcl::SACSegmentation<pcl::PointXYZ> seg;
pcl::ExtractIndices<pcl::PointXYZ> extract;
pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
seg.setOptimizeCoefficients(true);
seg.setModelType(pcl::SACMODEL_LINE);
seg.setMethodType(pcl::SAC_RANSAC);
seg.setDistanceThreshold(0.01);
pcl::PointCloud<pcl::PointXYZ>::Ptr remaining_points(new pcl::PointCloud<pcl::PointXYZ>(*cloud_boundary));
int line_count = 0;
while (remaining_points->size() > 10) {
seg.setInputCloud(remaining_points);
seg.segment(*inliers, *coefficients);
if (inliers->indices.empty()) break;
std::cout << "直线 " << ++line_count << " 系数: "
<< coefficients->values[0] << " " << coefficients->values[1] << " " << coefficients->values[2] << " "
<< coefficients->values[3] << " " << coefficients->values[4] << " " << coefficients->values[5] << std::endl;
pcl::PointCloud<pcl::PointXYZ>::Ptr line_points(new pcl::PointCloud<pcl::PointXYZ>);
extract.setInputCloud(remaining_points);
extract.setIndices(inliers);
extract.setNegative(false);
extract.filter(*line_points);
// 将已拟合的直线点从 remaining_points 中删除
extract.setNegative(true);
pcl::PointCloud<pcl::PointXYZ>::Ptr temp_points(new pcl::PointCloud<pcl::PointXYZ>);
extract.filter(*temp_points);
remaining_points.swap(temp_points);
}
}
int main(int argc, char* argv[]) {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("F:\\111.pcd", *cloud);
BoundaryExtraction(cloud, cloud_boundary, 200);
pcl::io::savePCDFile("F:\\boundary2.pcd", *cloud_boundary);
// 使用 RANSAC 拟合直线
FitBoundaryLines(cloud_boundary);
// 可视化边界点云
pcl::visualization::PCLVisualizer viewer("Boundary with Lines");
viewer.setBackgroundColor(0, 0, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler(cloud_boundary, 0, 255, 0);
viewer.addPointCloud(cloud_boundary, color_handler, "Boundary Points");
while (!viewer.wasStopped()) {
viewer.spinOnce(100);
}
return EXIT_SUCCESS;
}
标签:边界,16,points,pcl,点云,boundary,PointCloud,id,cloud
From: https://blog.csdn.net/qq_64095888/article/details/143700117