C C++最全点云处理基础操作_点云处理过程(2),2024金九银十面试季

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

PCL\_ERROR("Couldn't read file test\_pcd.pcd \n"); //文件不存在时,返回错误,终止程序。
getchar();
return (-1);

}

pcl::io::savePLYFile(“test.ply”, *cloud, true);


### 批量存取时文件名写法


string和stringstream区别:[string和stringstream用法总结](https://bbs.csdn.net/topics/618668825)



//简单版批量存储
//(在for循环里面)
std::stringstream ss, ss1;
ss << “tree3_cluster_” << j << “.pcd”;
ss1<< “tree3_cluster_” << j << “.ply”;
writer.write (ss.str (), *every_cluster, false);
writer1.write (ss1.str(), *every_cluster, false);
j++;


结合结构体以及字符串对点云进行批量存取:



//复杂版批量读取点云和存储点云
#include
#include
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>

string num2str(int i)
{
stringstream ss;
ss << i;
return ss.str();
}

//定义结构体,用于处理点云
struct PLY
{
std::string f_name; //文件名
pcl::PointCloudpcl::PointNormal::Ptr cloudWithNormal;//存储估计的法线的指针
pcl::PointCloudpcl::PointXYZ::Ptr cloud;//存储点云
//构造函数
PLY() : cloud(new pcl::PointCloudpcl::PointXYZ),cloudWithNormal(new pcl::PointCloudpcl::PointNormal){}; //初始化
};

int main()
{
const int numberOfViews = 6;//文件数量
std::vector<PLY, Eigen::aligned_allocator > data; //点云数据
std::vector<PLY, Eigen::aligned_allocator > data1; //点云数据
std::string prefix(“cow1”);
std::string extension(“_withNormal_boundary.ply”); //声明并初始化string类型变量extension,表示文件后缀名
// 通过遍历文件名,读取ply文件
for (int i = 0; i < numberOfViews; i++) //遍历所有的文件名
{
std::string fname = prefix + num2str(i) + extension;
// 读取点云,并保存到models
PLY m;
m.f_name = fname;
if (pcl::io::loadPLYFile(fname, *m.cloud) == -1) //* 读入PCD格式的文件,如果文件不存在,返回-1
{
cout << "Couldn’t read file " + fname + “.” << endl; //文件不存在时,返回错误,终止程序。
return (-1);
}
data.push_back(m);
}
//这样之后data[i].cloud就代表一个点云,共六个
//批量存储点云
for (int i = 0; i < numberOfViews; ++i)
{
std::string fname = prefix + num2str(i) + “_rotate” + extension;
pcl::io::savePLYFile(fname, *data[i].cloudWithNormal, true);
}

return 0;

}


还可以批量进行其他操作,比如离群点滤波



//-----------------------去除离群点------------------------
std::vector<PCD, Eigen::aligned_allocator<PCD> > data1; //这里新定义了一个算是数组?好像滤波之后的点云不能重复赋值到这个数组里
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
outrem.setRadiusSearch(0.01);
outrem.setMinNeighborsInRadius(5);
for (int i = 0; i < numberOfViews; ++i)
{
	PLY a;//这里新定义了一个结构体
	outrem.setInputCloud(data[i].cloud);
	outrem.filter(\*a.cloud);
	data1.push\_back(a);
}

### 注意!


批量处理点云时会出现定义新点云以及赋值的问题,这里一定要注意在赋值时先给他一个空间,否则如果只是一个指针的话很容易报错,什么指针溢出啥的,最后处理完成一定要设置好点云的长宽来保存点云  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210629152106297.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzkxMDk5,size_16,color_FFFFFF,t_70)


## 2. 定义一个新的点云


\*cloud是已知的点云  
 \*newcloud是新点云



pcl::PointCloudpcl::PointXYZRGB::Ptr newcloud(new pcl::PointCloudpcl::PointXYZRGB); // 创建点云(指针)

newcloud->height = cloud->height;//或者直接这个newcloud->height = 1;一般好像点云这个都是1
newcloud->width = cloud->width;//*cloud是已知的点云
newcloud->is_dense = false;


也可以直接复制点云



pcl::PointCloudpcl::PointXYZRGB::Ptr newcloud(new pcl::PointCloudpcl::PointXYZRGB); // 创建点云(指针)

pcl::copyPointCloud(*cloud, *newcloud);//把cloud复制给newcloud(然后就可以直接用newcloud了,里面就有相应点的坐标了,相当于把指针赋值了吧)注意一定要加这个,否则没法给新点云的点赋值啥的
//一顿操作之后newcloud里面一些点被修改,需要保存起来,如下:
newcloud->height = 1;
newcloud->width = newcloud->points.size();
newcloud->is_dense = false;


创建新点云并且给它赋值:



pcl::PointCloudpcl::PointXYZ::Ptr centorid_points(new pcl::PointCloudpcl::PointXYZ);

for (int i = 0; i < numberOfViews; i++)
{
	pcl::PointXYZ point; 
	Eigen::Vector4f centroid;					// 质心
	pcl::compute3DCentroid(\*data1[i].cloud, centroid);	// 齐次坐标,(c0,c1,c2,1)
	point.x = centroid(0); //这里直接给点云赋值(centorid_points->points[i].x=centroid(0);)是不行的,要先给点赋值,然后再把点push_back到点云中
	point.y = centroid(1);
	point.z = centroid(2);
	//cout << centroid(0)<<endl;
	centorid_points->points.push\_back(point);
}
centorid_points->height = 1;
centorid_points->width = numberOfViews;
centorid_points->is_dense = false;

有序点云的保存



pcl::PointCloud<pcl::PointXYZ> newcloud;
newcloud.width = 424;
newcloud.height = 512;
newcloud.points.resize(newcloud.width\*newcloud.height);//要加这个,否则会报错
newcloud.is_dense = false;//点云中有NAN值,若没有则true,或者说数值是有限则是true
for (int i = 0; i < cloud->size(); i++)
{
	newcloud.points[i].x = cloud->points[i].x;
	newcloud.points[i].y = cloud->points[i].y;
	newcloud.points[i].z = cloud->points[i].z;
	/\*std::cout << i << endl;\*/
}
pcl::io::savePLYFile("newcloud.ply", newcloud);

## 3. 去除NAN点



#include <pcl/filters/extract_indices.h>
#include <pcl/filters/filter.h> //这两个任意一个头文件好像就可以
//去除NAN点
std::vector mapping;
pcl::removeNaNFromPointCloud(*pcloud, *pcloud, mapping);
std::cout << "原始点云去除NaN点后数量: " << pcloud->points.size() << std::endl;


注意这里如果是复制的指针,去除之前一定要先保存点云,否则没啥效果



pcl::copyPointCloud(\*source_key_Neigh, \*source_key_Neighbors);
for (int n = 0; n < source_key_Neigh->size(); n++)
{
	for (int m = 0; m < source_key_Neigh->size(); m++)
	{
		if ((source_key_Neigh->points[n].x == source_key_Neighbors->points[m].x) && (source_key_Neigh->points[n].y == source_key_Neighbors->points[m].y) && (source_key_Neigh->points[n].z == source_key_Neighbors->points[m].z) && (m != n))
		{
			source_key_Neighbors->points[m].x = NAN;
			source_key_Neighbors->points[m].y = NAN;
			source_key_Neighbors->points[m].z = NAN;
		}
	}
}
// 设置并保存点云\*\*\*\*\*\*\*\*\*\*\*保存这里很重要
source_key_Neighbors->height = 1;
source_key_Neighbors->width = source_key_Neighbors->points.size();
source_key_Neighbors->is_dense = false;
//去除NAN点
std::vector<int> mapping;
pcl::removeNaNFromPointCloud(\*source_key_Neighbors, \*source_key_Neighbors, mapping);

## 4. 遍历点云




![img](https://img-blog.csdnimg.cn/img_convert/5d0b34af7d6bcc3c5a49f8a9ebf86c34.png)
![img](https://img-blog.csdnimg.cn/img_convert/e000a725a772da5fc2116c754397e51a.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

-1715708506034)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值