了解下最小分割算法,感觉对我的用处不是很大,我目前在了解关于移动无物体进行实时分割,最小分割算法是针对静态的物体进行的,并且设置的参数也比较多,还需要对分割的物体的中心点进行保存,如果中心点可以进行实时更新,硬件的处理能力够好的话也可以进行实时检测。
最小分割算法
该算法是将一幅点云图像分割为两部分:前景点云(目标物体)和背景物体(剩余部分)
如果要分开最左边的点和最右边的点,红绿两种割法都是可行的,但是红线跨过了三条线,绿线只跨过了两条。单从跨线数量上来论可以得出绿线这种切割方法更优 的结论。但假设线上有不同的权值,那么最优切割则和权值有关了。当你给出了点之间的 “图” ,以及连线的权值时,最小割算法就能按照要求把图分开。
所以那么怎么来理解点云的图呢?
显而易见,切割有两个非常重要的因素,第一个是获得点与点之间的拓扑关系,这种拓扑关系就是生成一张 “图”。第二个是给图中的连线赋予合适的权值。只要这两个要素合适,最小割算法就会正确的分割出想要的结果。点云是分开的点。只要把点云中所有的点连起来就可以了。连接算法如下:
- 找到每个点临近的n个点
- 将这n个点和父点连接
- 找到距离最小的两个块(A块中某点与B块中某点距离最小),并连接
- 重复3,直至只剩一个块
经过上面的步骤现在已经有了点云的“图”,只要给图附上合适的权值,就满足了最小分割的前提条件。物体分割比如图像分割给人一个直观印象就是属于该物体的点,应该相互之间不会太远。也就是说,可以用点与点之间的欧式距离来构造权值。所有线的权值可映射为线长的函数。
我们知道这种分割是需要指定对象的,也就是我们指定聚类的中心点(center)以及聚类的半径(radius),当然我们指定了中心点和聚类的半径,那么就要被保护起来,保护的方法就是增加它的权值
下面是pcl官方网站的代码
#include <iostream>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/min_cut_segmentation.h>
int main (int argc, char** argv)
{
pcl::PointCloud <pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud <pcl::PointXYZ>);
if ( pcl::io::loadPCDFile <pcl::PointXYZ> ("min_cut_segmentation_tutorial.pcd", *cloud) == -1 )
{
std::cout << "Cloud reading failed." << std::endl;
return (-1);
}
pcl::IndicesPtr indices (new std::vector <int>);
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud);
pass.setFilterFieldName ("z");
pass.setFilterLimits (0.0, 1.0);
pass.filter (*indices);
pcl::MinCutSegmentation<pcl::PointXYZ> seg;
seg.setInputCloud (cloud);
seg.setIndices (indices);
pcl::PointCloud<pcl::PointXYZ>::Ptr foreground_points(new pcl::PointCloud<pcl::PointXYZ> ());
pcl::PointXYZ point;
point.x = 68.97;
point.y = -18.55;
point.z = 0.57;
foreground_points->points.push_back(point);
seg.setForegroundPoints (foreground_points);
seg.setSigma (0.25);
seg.setRadius (3.0433856);
seg.setNumberOfNeighbours (14);
seg.setSourceWeight (0.8);
std::vector <pcl::PointIndices> clusters;
seg.extract (clusters);
std::cout << "Maximum flow is " << seg.getMaxFlow () << std::endl;
pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = seg.getColoredCloud ();
pcl::visualization::CloudViewer viewer ("Cluster viewer");
viewer.showCloud(colored_cloud);
while (!viewer.wasStopped ())
{
}
return (0);
}
分类: PCL