摘要
本文使用基于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模型的前提下,通过提取点对或者法向特征完成统计后与现场各个点云聚类比较,实现现场聚类筛选。