pcl案例1 平面找凹凸区域

发布于:2025-08-29 ⋅ 阅读:(21) ⋅ 点赞:(0)

一,在这个点云平面上存在一个大的凹凸点需要被提取。

    如果大牛可能能找出来三个,还有两个小坑点

二,这里找了一个展示一下

理想状态应该是这样的,但下采样以后两小的很难被找到。

三,下面是我的代码,如果你有更好的办法,欢迎留言

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <thread>
#include <pcl/io/ply_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include<pcl/common/common.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/octree/octree.h>
#include<pcl/search/octree.h>
#include <pcl/features/moment_of_inertia_estimation.h>
#include<pcl/features/moment_invariants.h>
#include<pcl/features/normal_3D.h>
#include<pcl/filters/bilateral.h>
#include<pcl/filters//conditional_removal.h>
#include<pcl/surface/mls.h>
#include<pcl/filters/random_sample.h>
#include<pcl/common/transforms.h>
#include<pcl/common/geometry.h>
#include<pcl/filters/voxel_grid.h>
#include<pcl/filters/bilateral.h>

#include "tolls.h"

using namespace std;

//按比列下采样函数
template<class pointT>
class pcl::PointCloud<pointT>::Ptr down_sample(class pcl::PointCloud<pointT>::Ptr input_cloud,float down_rate )
{
	int dowm_sample_num = (int)input_cloud->points.size() * down_rate;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_10(new pcl::PointCloud<pcl::PointXYZ>());
	//降10倍快速下采样
	pcl::RandomSample<pcl::PointXYZ> rs;
	rs.setInputCloud(input_cloud);
	rs.setSeed(42);
	rs.setSample(dowm_sample_num);
	rs.filter(*cloud_10);
	return cloud_10;

}


//将点云自身xyz按比例放大
template<class pointT1>
void scale_pointcloud(class pcl::PointCloud<pointT1>::Ptr input_cloud, vector<float> rate) 
{
	Eigen::Matrix4f trans_scale = Eigen::Matrix4f::Identity();
	trans_scale(0, 0) = rate[0];
	trans_scale(1, 1) = rate[1];
	trans_scale(2, 2) = rate[2];
	//trans_scale = trans_scale.eval();
	pcl::transformPointCloud<pointT1>(*input_cloud, *input_cloud, trans_scale);
}


int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	// 加载bun0.pcd文件,加载的文件在 PCL的测试数据中是存在的 
	pcl::io::loadPLYFile("D:\\Desktop\\pacl_learning\\case\\01.ply", *cloud);
	pcl::PointXYZ p_min, p_max;
	pcl::getMinMax3D<pcl::PointXYZ>(*cloud, p_min, p_max);
	//得到点云的数量是645856,x方向是0.056m,y方向是0.112m;不好计算,换算成毫米进行1000倍的缩放
	vector<float> scale = { 1000,1000,2000 };
	scale_pointcloud<pcl::PointXYZ>(cloud, scale);
	cout << "原始点云数___" << cloud->points.size() << endl;
	pcl::getMinMax3D<pcl::PointXYZ>(*cloud, p_min, p_max);
	cout << "缩放后点云高度——" << p_max.z - p_min.z << endl;

	//先进行体素下采样
	pcl::VoxelGrid<pcl::PointXYZ> voxelGrid;
	voxelGrid.setInputCloud(cloud);
	voxelGrid.setLeafSize(0.6f, 0.6f, 0.04f); // 每个体素的大小
	pcl::PointCloud<pcl::PointXYZ>::Ptr voxelCloud(new pcl::PointCloud<pcl::PointXYZ>);
	voxelGrid.filter(*voxelCloud);
	cout << voxelCloud->points.size() << endl;
	pcl::getMinMax3D<pcl::PointXYZ>(*cloud, p_min, p_max);
	cout << "体素滤波后点云高度——" << p_max.z - p_min.z << endl;
	//show_pointcloud<pcl::PointXYZ>(voxelCloud);

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_defect(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZ>);
	tree2->setInputCloud(voxelCloud);
	vector<int> ind;
	vector<float> ds;
	for (int i = 0; i < voxelCloud->points.size(); i++)
	{
		
		tree2->radiusSearch(voxelCloud->points[i], 2.8, ind, ds);
		vector<float> dz;
		for (int n =0;n<ind.size();n++)
		{
			dz.push_back(voxelCloud->points[ind[n]].z);
		}
		sort(dz.begin(), dz.end());
		

		float a = abs(voxelCloud->points[i].z - dz[round(ind.size()*0.5)]);
		if (a>0.18)
		{
			cloud_defect->push_back(voxelCloud->points[i]);
		}

	}
	cout << cloud_defect->points.size() << endl;

	pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer(""));
	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color(voxelCloud, 255, 0, 0);
	viewer->addPointCloud(voxelCloud, color, "cloud1");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud1");

	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color1(cloud_defect, 0, 255, 0);
	viewer->addPointCloud(cloud_defect, color1, "defect");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "defect");
	viewer->addCoordinateSystem(2, "cloud1");

	while (!viewer->wasStopped()) {
		viewer->spinOnce(100);
	}
	
}






网站公告

今日签到

点亮在社区的每一天
去签到