****只适用于位于同一平面上的点云数据,进行边缘点检测
一、原理介绍
有序边缘点,就是提取的边缘点具有先后顺序,连接起来能够大体描述点云形状。如下图所示为有序边缘点,其连接成的多边形大体准确刻画了点云外部形状。而下面的一副图,其提取的边缘点为无序边缘点。无序边缘点一般后面需要 进行有序排列,其难度依据点云形状而定。
下面介绍一种使用alpha shapes算法提取边缘点,并进行排序的方法,其先使用alpha shapes算法提取边缘点,再进行排序。
代码下载链接:https://download.csdn.net/download/qq_32867925/87429769?spm=1001.2014.3001.5503
二、源码测试及实验结果
****再次声明:其只适用于位于同一平面上的点云数据,进行边缘点检测
运行环境:PCL1.8版本及以上,IDE:vs2013
单独运行cpp文件即可。
(1)边缘点提取实验(部分核心代码展示)
//测试边缘提取结果
void main01()
{
char *inputpath = "E:\\testdata.xyz";
char *outpath = "E:\\result.xyz";
//(1)读入点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud = XYZ2PCDPtr(inputpath);
//(2)边缘检测
double r = 1.2;
vector<pcl::PointXYZ> bound, non_bound;
boundExtract(cloud, r, bound, non_bound);
ofstream outfile(outpath, ios::out);
for (int i = 0; i < bound.size(); i++)
{
outfile << fixed << setprecision(3) << bound[i].x << " " << bound[i].y << " " << bound[i].z << " " << fixed << setprecision(0) <<
255 << " " << 0 << " " << 0 << endl;
}
for (int i = 0; i < non_bound.size(); i++)
{
outfile << fixed << setprecision(3) << non_bound[i].x << " " << non_bound[i].y << " " << non_bound[i].z << " " << fixed << setprecision(0) <<
255 << " " << 255 << " " << 255 << endl;
}
outfile.close();
system("pause");
}
其结果如下,整体上来说还是不错的,提取的边缘点比较简洁
(2)测试边缘点是否有序(部分核心代码展示):
//测试边缘点的有序性
void main()
{
char *inputpath = "E:\\testdata.xyz";
//char *inputpath = "E:\\testdata_01.xyz";
//(1)读入点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud = XYZ2PCDPtr(inputpath);
//(2)边缘检测
double r = 1.2;
vector<pcl::PointXYZ> bound, non_bound;
boundExtract(cloud, r, bound, non_bound);
//(3)可视化
pcl::visualization::PCLVisualizer viewer("outline view");
viewer.setBackgroundColor(0, 0, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 0, 255);
viewer.addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");//设置点云大小
//(4)增加多边形
pcl::PlanarPolygon<pcl::PointXYZ> polygon;
pcl::PointCloud<pcl::PointXYZ> contour;
contour.width = bound.size();
contour.height = 1;
contour.is_dense = false;
contour.resize(contour.height*contour.width);
for (int i = 0; i < bound.size(); i++)
{
contour.points[i] = bound[i];
}
polygon.setContour(contour);
viewer.addPolygon(polygon, 255, 0, 0, "ploygon", 0);
//(5)增加点
pcl::PointCloud<pcl::PointXYZ>::Ptr Boun_Cloud(new pcl::PointCloud<pcl::PointXYZ>);
Boun_Cloud->width = bound.size();
Boun_Cloud->height = 1;
Boun_Cloud->is_dense = false;
Boun_Cloud->resize(Boun_Cloud->width*Boun_Cloud->height);
for (int i = 0; i < Boun_Cloud->width; i++)
{
Boun_Cloud->points[i] = bound[i];
}
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> singleColor(Boun_Cloud, 0, 255, 0);//0-255 设置成绿色
viewer.addPointCloud<pcl::PointXYZ>(Boun_Cloud, singleColor, "sample");//显示点云,其中fildColor为颜色显示
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample");//设置点云大小
while (!viewer.wasStopped())
{
viewer.spinOnce(1);
}
}
其对于凸包、凹包形状的点云数据均可以提取出,表现出较强的稳健性