只有想法而不去实践是不现实的,这样下去前进的脚步将会非常慢。
达到效果:1、将一个海之言的瓶子分割成梯形状和矩形状,将两种进行体积求和;
2、升级任务:利用微积分,将一个对称的不规则边缘物体的体积积出来。
首先开启激光雷达采集一下点云,查看点云的轮廓和形状和自己判断是否一致。
简直不能理解,为什么海之言的瓶子中间会扫描不到,难道因为这种特别的流线型,导致点传不回来吗?干脆换一个瓶子。
(PS:宇树科技激光雷达x轴正方向判断:接线端的反方向即为x轴正方向,逆时针90°即为y轴的正方向。)
换一个瓶子后扫描的点如图:
现在的目标就很明确了,将该点云分成三块,第一块上面的瓶盖(圆柱);第二块下面的长方体;第三块就是二者之间的一块梯形体。现在要将三块标出来,并且得到三块的长度,将三者体积相加。
接下来,首先对获取的图像进行滤波,然后滤波之后的物体进行识别、标注、计算。
滤波:这里选择使用半径滤波去除离群点,以及使用体素网格滤波
// 加载点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>(argc > 1 ? argv[1] : "b.pcd", *cloud) == -1) {
PCL_ERROR("无法加载PCD文件\n");
return (-1);
}
// 预处理:半径滤波去除离群点
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(0.002);
outrem.setMinNeighborsInRadius(8);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
outrem.filter(*cloud_filtered);
// 预处理:体素网格滤波
pcl::VoxelGrid<pcl::PointXYZ> vg;
vg.setInputCloud(cloud_filtered);
vg.setLeafSize(0.007f, 0.007f, 0.007f);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_voxel_grid(new pcl::PointCloud<pcl::PointXYZ>);
vg.filter(*cloud_voxel_grid);
// 保存滤波后的点云
pcl::io::savePCDFileASCII("filtered_cloud.pcd", *cloud_voxel_grid);
得到的效果如下图所示:(下面这一段是当初扫描的时候加的一层板子,暂时可以忽略)
我们可以看到,比较好的将上下两个形状区别开来,其实我这里想再用一个半径滤波,应该就可以比较好的分开来了。