基于RGB_D图像的现场点云分割(d435i c++ pcl)

  • Post author:
  • Post category:其他

摘要

本文使用基于RGB信息的区域生长分割算法完成对现场图像的快速分割(小于1s)。首先使用D435i相机获取现场RGB和Depth信息生成带有彩色信息的点云,并获取点云进行下采样,之后对约简点云进行分割。

实现

现场ply文件捕捉实现:

(6条消息) 利用IntelRealSense D435i 提取一帧pcl::PointXYZRGB图像(C++)_m0_56838271的博客-CSDN博客


#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/passthrough.h>
#include <pcl/segmentation/region_growing_rgb.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/console/time.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/filters/voxel_grid.h>

int main(int argc, char** argv)
{
	bool Bool_Cuting = false, b_n = false;
	int MinClusterSize = 600, KN_normal = 50;
	float far_cuting = 10, near_cuting = 0, DistanceThreshold = 10.0, ColorThreshold = 6, RegionColorThreshold = 5, SmoothnessThreshold = 30.0, CurvatureThreshold = 0.05;
	
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_t(new pcl::PointCloud<pcl::PointXYZRGB>);
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

	pcl::VoxelGrid<pcl::PointXYZRGB> sor;
	
	time_t start, end, diff[5], option;//计时相关

	pcl::io::loadPCDFile("colorful.pcd", *cloud_t);

	sor.setInputCloud(cloud_t);
	sor.setLeafSize(0.005f, 0.005f, 0.005f);
	sor.filter(*cloud);
	cout<<cloud->points.size()<<endl;
	pcl::search::Search <pcl::PointXYZRGB>::Ptr tree = boost::shared_ptr<pcl::search::Search<pcl::PointXYZRGB> >(new pcl::search::KdTree<pcl::PointXYZRGB>);


	pcl::search::Search<pcl::PointXYZRGB>::Ptr tree1 = boost::shared_ptr<pcl::search::Search<pcl::PointXYZRGB> >(new pcl::search::KdTree<pcl::PointXYZRGB>);
	pcl::PointCloud <pcl::Normal>::Ptr normals(new pcl::PointCloud <pcl::Normal>);
	pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> normal_estimator;
	normal_estimator.setSearchMethod(tree);
	normal_estimator.setInputCloud(cloud);
	normal_estimator.setKSearch(KN_normal);
	normal_estimator.compute(*normals);
	end = time(0);
	diff[1] = difftime(end, start) - diff[0];
	PCL_INFO("\tEstimating normal takes(seconds): %d\n", diff[1]);

	pcl::IndicesPtr indices(new std::vector <int>);
	if (Bool_Cuting)
	{

		pcl::PassThrough<pcl::PointXYZRGB> pass;
		pass.setInputCloud(cloud);
		pass.setFilterFieldName("z");
		pass.setFilterLimits(near_cuting, far_cuting);
		pass.filter(*indices);
	}

	pcl::RegionGrowingRGB<pcl::PointXYZRGB> reg;
	reg.setInputCloud(cloud);
	if (Bool_Cuting)reg.setIndices(indices);
	reg.setSearchMethod(tree);
	reg.setDistanceThreshold(DistanceThreshold);
	reg.setPointColorThreshold(ColorThreshold);
	reg.setRegionColorThreshold(RegionColorThreshold);
	reg.setMinClusterSize(MinClusterSize);
	if (b_n)
	{
		reg.setSmoothModeFlag(true);
		reg.setCurvatureTestFlag(true);

		reg.setInputNormals(normals);
		reg.setSmoothnessThreshold(SmoothnessThreshold / 180.0 * M_PI);
		reg.setCurvatureThreshold(CurvatureThreshold);
	}
	std::vector <pcl::PointIndices> clusters;
	reg.extract(clusters);
	end = time(0);
	diff[2] = difftime(end, start) - diff[0] - diff[1];
	PCL_INFO("\tRGB region growing takes(seconds): %d\n", diff[2]);

	std::cout << "number of cluster : " << clusters.size() << std::endl;

	pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud();
	pcl::visualization::CloudViewer viewer("基于颜色的区域生长算法实现点云分割");
	viewer.showCloud(colored_cloud);
	while (!viewer.wasStopped())
	{
		boost::this_thread::sleep(boost::posix_time::microseconds(100));
	}
	return 0;
}

此处参考:点云下采样基于RGB的区域生长

结果

工作展望

下一步在给定茶杯CAD模型的前提下,通过提取点对或者法向特征完成统计后与现场各个点云聚类比较,实现现场聚类筛选。


版权声明:本文为m0_56838271原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。