PCL point cloud segmentation minimum cut algorithm

It is widely used in background segmentation, stereo vision, matting and so on.

GraphCuts graphs have two more vertices on the basis of ordinary graphs, which are represented by the symbols * * S "and" T "*, collectively referred to as terminal vertices. All other vertices must be connected with these two vertices to form a part of the edge set. So there are two kinds of vertices and two kinds of edges in Graph Cuts.
The first type of vertex and edge is: the first type of ordinary vertex corresponds to each pixel in the image. The connection of every two neighborhood vertices (corresponding to every two neighborhood pixels in the image) is an edge. This edge is also called n-links.
The second kind of vertex and edge are: in addition to image pixels, there are two other terminal vertices, called S (source: source point, take the meaning of source) and T (sink: sink, take the meaning of convergence). Each ordinary vertex and these two terminal vertices are connected to form the second kind of edge. This kind of edge is also called t-links.
The minimum cut algorithm is implemented in PCL:
(1) Construction graph: for a given point cloud, the algorithm will add a source (source point) and a sink (sink) to each point in the point cloud as the vertex of the GraphCut graph; the edge formed by connecting each point in the point cloud with its nearest neighbors is called n-links, and the edge formed by connecting with sink and source is called t-links.
(2) Weight value of opposite side:

(3) Minimum cut calculation: the point cloud is divided into foreground and background.
Code:

#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>
//#include <pcl/console/print.h>
//#include <pcl/console/parse.h>
//#include <pcl/console/time.h>
//using namespace pcl::console;
int main()
{
/*	if (argc<2)
	{
		std::cout << ".exe xx.pcd -bc 1 -fc 1.0 -nc 0 -cx 68.97 -cy -18.55 -cz 0.57 -s 0.25 -r 3.0433856 -non 14 -sw 0.5" << endl;

		return 0;
	}//If the input parameter is less than 1, the prompt message will be output
	time_t start, end, diff[5], option;
	start = time(0);
	*/
	int NumberOfNeighbours = 14;//Set default parameters
	bool Bool_Cuting = false;//Set default parameters
	float far_cuting = 1, near_cuting = 0, C_x = 0.071753, C_y = -0.309913, C_z = 1.603000, Sigma = 0.25, Radius = 0.8, SourceWeight = 0.5;//Set default input parameters
	pcl::PointCloud <pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud <pcl::PointXYZ>);// Create a pointcloud < PCL:: pointxyzrgb > shared pointer and instantiate it
	if (pcl::io::loadPCDFile <pcl::PointXYZ>("min_cut_segmentation_tutorial.pcd", *cloud) == -1)// Load point cloud data
	{
		std::cout << "Cloud reading failed." << std::endl;
		return (-1);
	}

/*	parse_argument(argc, argv, "-bc", Bool_Cuting);
	parse_argument(argc, argv, "-fc", far_cuting);
	parse_argument(argc, argv, "-nc", near_cuting);

	parse_argument(argc, argv, "-cx", C_x);
	parse_argument(argc, argv, "-cy", C_y);
	parse_argument(argc, argv, "-cz", C_z);

	parse_argument(argc, argv, "-s", Sigma);
	parse_argument(argc, argv, "-r", Radius);
	parse_argument(argc, argv, "-non", NumberOfNeighbours);
	parse_argument(argc, argv, "-sw", SourceWeight);//Set input parameter mode
*/
	pcl::IndicesPtr indices(new std::vector <int>);//Create a set of indexes
	if (Bool_Cuting)//Determine whether through filtering is required
	{
		pcl::PassThrough<pcl::PointXYZ> pass;//Set pass through filter object
		pass.setInputCloud(cloud);//Set input point cloud
		pass.setFilterFieldName("z");//Set dimensions for specified filtering
		pass.setFilterLimits(near_cuting, far_cuting);//Set the range of specified latitude filtering
		pass.filter(*indices);//Perform filtering and save the filtering results in the above index

	}
	pcl::MinCutSegmentation<pcl::PointXYZ> seg;//Create a PointXYZRGB type region growing segmentation object
	seg.setInputCloud(cloud);//Set input point cloud
	if (Bool_Cuting)seg.setIndices(indices);//Set index of input point cloud

	pcl::PointCloud<pcl::PointXYZ>::Ptr foreground_points(new pcl::PointCloud<pcl::PointXYZ>());//Create a pointcloud < PCL:: pointxyzrgb > shared pointer and instantiate it
	pcl::PointXYZ point;//Define center point and assign value

	point.x = C_x;
	point.y = C_y;
	point.z = C_z;
	foreground_points->points.push_back(point);
	seg.setForegroundPoints(foreground_points);//Enter the center point of the foreground point cloud (target object)

	seg.setSigma(Sigma);//Set Sigma value for smoothing cost
	seg.setRadius(Radius);//Set the radius of the background penalty weight
	seg.setNumberOfNeighbours(NumberOfNeighbours);//Set the number of adjacent points
	seg.setSourceWeight(SourceWeight);//Set foreground penalty weight

	std::vector <pcl::PointIndices> clusters;
	seg.extract(clusters);//The segmentation result is obtained and saved in the vector of the point cloud index.

	std::cout << "Maximum flow is " << seg.getMaxFlow() << std::endl;//Calculate and output the flow value calculated during the split

	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = seg.getColoredCloud();//Give red to the former scenic spot and white to the background point.
	pcl::visualization::PCLVisualizer viewer("Point cloud Library PCL Learning Course Second Edition-Minimum cut segmentation method");
	viewer.addPointCloud(colored_cloud);
	viewer.addSphere(point, Radius, 122, 122, 0, "sphere");
	viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY, 0.2, "sphere");

	while (!viewer.wasStopped())
	{
		viewer.spin();
	}//Visualizing

	return (0);
}


vtk error in point cloud display, debug later!

Published 28 original articles, won praise 2, visited 937
Private letter follow

Tags: PCL less

Posted on Mon, 09 Mar 2020 01:56:04 -0700 by dnszero