wap手机网站开发软件,wordpress编辑器不行,软件开发能力,如何网页设计与制作#xff08;二十七#xff09;基于法线差的点云分割 图片来源
提出这个方法的论文#xff1a;Difference of Normals as a Multi-Scale Operator in Unorganized Point Clouds
算法流程#xff1a; 在大尺度的范围内#xff08;半径 r 1 r_1 r1#xff09;估计每个点…二十七基于法线差的点云分割 图片来源
提出这个方法的论文Difference of Normals as a Multi-Scale Operator in Unorganized Point Clouds
算法流程 在大尺度的范围内半径 r 1 r_1 r1估计每个点的法线 在晓尺度的范围半径 r 2 r_2 r2估计每个点的法线 计算法线差Difference of Normals (DoN) 根据设定的法线差阈值过滤点 对剩余的点进行欧几里得分割。
don_segmentation.cpp
/*** file don_segmentation.cpp* Difference of Normals Example for PCL Segmentation Tutorials.** author Yani Ioannou* date 2012-09-24*/
#include string
#include pcl/point_types.h
#include pcl/io/pcd_io.h
#include pcl/search/organized.h
#include pcl/search/kdtree.h
#include pcl/features/normal_3d_omp.h
#include pcl/filters/conditional_removal.h
#include pcl/segmentation/extract_clusters.h
#include pcl/features/don.husing namespace pcl;int main (int argc, char *argv[])
{///The smallest scale to use in the DoN filter.double scale1;///The largest scale to use in the DoN filter.double scale2;///The minimum DoN magnitude to threshold bydouble threshold;///segment scene into clusters with given distance tolerance using euclidean clusteringdouble segradius;if (argc 6){std::cerr usage: argv[0] inputfile smallscale largescale threshold segradius std::endl;exit (EXIT_FAILURE);}/// the file to read from.std::string infile argv[1];/// small scalestd::istringstream (argv[2]) scale1;/// large scalestd::istringstream (argv[3]) scale2;std::istringstream (argv[4]) threshold; // threshold for DoN magnitudestd::istringstream (argv[5]) segradius; // threshold for radius segmentation// Load cloud in blob formatpcl::PCLPointCloud2 blob;pcl::io::loadPCDFile (infile.c_str (), blob);pcl::PointCloudPointXYZRGB::Ptr cloud (new pcl::PointCloudPointXYZRGB);pcl::fromPCLPointCloud2 (blob, *cloud);// OrganizedNeighbor适用于有组织的数据。KDTree适用于无组织的数据pcl::search::SearchPointXYZRGB::Ptr tree;if (cloud-isOrganized ()){tree.reset (new pcl::search::OrganizedNeighborPointXYZRGB ());}else{tree.reset (new pcl::search::KdTreePointXYZRGB (false));}// Set the input pointcloud for the search treetree-setInputCloud (cloud);if (scale1 scale2){std::cerr Error: Large scale must be small scale! std::endl;exit (EXIT_FAILURE);}// 计算每个点小尺度和大尺度的法线// 通过OpenMP多线程使用处理器中的多个内核来计算法线pcl::NormalEstimationOMPPointXYZRGB, PointNormal ne; // PointNormal-float x,y,z,normal[3], curvaturene.setInputCloud (cloud);ne.setSearchMethod (tree);// 设置一个在所有法线计算中使用的视点,确保了在不同尺度上估计的法线的基本方向一致。ne.setViewPoint (std::numeric_limitsfloat::max (), std::numeric_limitsfloat::max (), std::numeric_limitsfloat::max ());// calculate normals with the small scalestd::cout Calculating normals for scale... scale1 std::endl;pcl::PointCloudPointNormal::Ptr normals_small_scale (new pcl::PointCloudPointNormal);ne.setRadiusSearch (scale1);ne.compute (*normals_small_scale);// calculate normals with the large scalestd::cout Calculating normals for scale... scale2 std::endl;pcl::PointCloudPointNormal::Ptr normals_large_scale (new pcl::PointCloudPointNormal);ne.setRadiusSearch (scale2);ne.compute (*normals_large_scale);// Create output cloud for DoN resultsPointCloudPointNormal::Ptr doncloud (new pcl::PointCloudPointNormal);copyPointCloud (*cloud, *doncloud);std::cout Calculating DoN... std::endl;// DoN 估计模板的3个参数第一个对应于输入点云类型,第二个对应于为点云估计的法线类型.第三个对应于输出类型pcl::DifferenceOfNormalsEstimationPointXYZRGB, PointNormal, PointNormal don;don.setInputCloud (cloud);don.setNormalScaleLarge (normals_large_scale);don.setNormalScaleSmall (normals_small_scale);if (!don.initCompute ()){std::cerr Error: Could not initialize DoN feature operator std::endl;exit (EXIT_FAILURE);}// Compute DoNdon.computeFeature (*doncloud);// Save DoN featurespcl::PCDWriter writer;writer.writepcl::PointNormal (don.pcd, *doncloud, false); std::cout Filtering out DoN mag threshold ... std::endl;// 设定滤波条件根据点的法线差矢量过滤点 pcl::ConditionOrPointNormal::Ptr range_cond (new pcl::ConditionOrPointNormal ());// curvature 过滤DoN的l2范数小于threshold的点range_cond-addComparison (pcl::FieldComparisonPointNormal::ConstPtr (new pcl::FieldComparisonPointNormal (curvature, pcl::ComparisonOps::GT, threshold)));// 创建条件滤波器pcl::ConditionalRemovalPointNormal condrem;condrem.setCondition (range_cond);condrem.setInputCloud (doncloud);pcl::PointCloudPointNormal::Ptr doncloud_filtered (new pcl::PointCloudPointNormal);// Apply filtercondrem.filter (*doncloud_filtered);doncloud doncloud_filtered;// Save filtered outputstd::cout Filtered Pointcloud: doncloud-size () data points. std::endl;writer.writepcl::PointNormal (don_filtered.pcd, *doncloud, false); // 欧几里得聚类分割std::cout Clustering using EuclideanClusterExtraction with tolerance segradius ... std::endl;pcl::search::KdTreePointNormal::Ptr segtree (new pcl::search::KdTreePointNormal);segtree-setInputCloud (doncloud);std::vectorpcl::PointIndices cluster_indices;pcl::EuclideanClusterExtractionPointNormal ec;ec.setClusterTolerance (segradius);ec.setMinClusterSize (50);ec.setMaxClusterSize (100000);ec.setSearchMethod (segtree);ec.setInputCloud (doncloud);ec.extract (cluster_indices);int j 0;for (const auto cluster : cluster_indices){pcl::PointCloudPointNormal::Ptr cloud_cluster_don (new pcl::PointCloudPointNormal);for (const auto idx : cluster.indices){cloud_cluster_don-points.push_back ((*doncloud)[idx]);}cloud_cluster_don-width cloud_cluster_don-size ();cloud_cluster_don-height 1;cloud_cluster_don-is_dense true;//Save clusterstd::cout PointCloud representing the Cluster: cloud_cluster_don-size () data points. std::endl;std::stringstream ss;ss don_cluster_ j .pcd;writer.writepcl::PointNormal (ss.str (), *cloud_cluster_don, false);j;}
}CMakeLists.txt
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)project(don_segmentation)find_package(PCL 1.7 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})add_executable (don_segmentation don_segmentation.cpp)
target_link_libraries (don_segmentation ${PCL_LIBRARIES})数据样例
编译并运行
$ ./don_segmentation inputfile smallscale largescale threshold segradius$./don_segmentation 003000.pcd 0.4 2 0.2 0.5DoN
根据DoN滤除点 聚类