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);
}### 注意!
批量处理点云时会出现定义新点云以及赋值的问题,这里一定要注意在赋值时先给他一个空间,否则如果只是一个指针的话很容易报错,什么指针溢出啥的,最后处理完成一定要设置好点云的长宽来保存点云
![在这里插入图片描述]()
## 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. 遍历点云
C++里,是编号是从0开始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;
}
}
}matlab里编号是从1 开始ptCloud = pcread(‘source_key_Neigh.ply’);
location=ptCloud.Location;
x = location(:,1);
y = location(:,2);
z = location(:,3);
location1=location;
x1=x;
y1=y;
z1=z;
for i=1:size(x)
for j=1:size(x)
if((x1(j)==x(i))&&(y1(j)==y(i))&&(z1(j)==z(i))&&(i~=j))
location1(j,1)=nan;
location1(j,2)=nan;
location1(j,3)=nan;
end
end
end
location1(all(isnan(location1), 2)😅 = [];## 5. 查看点云点数#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>using namespace std;
typedef pcl::PointXYZRGBA PointT;int main()
{
pcl::PointCloudpcl::PointXYZRGB::Ptr cloud(new pcl::PointCloudpcl::PointXYZRGB);
pcl::PointCloudpcl::PointXYZRGB::Ptr cloud_filtered(new pcl::PointCloudpcl::PointXYZRGB);
std::string prefix(“2020-10-14-15-19-55_ConditionAnd_RadiusOutlierRemoval”);
std::string extension(“.ply”);
std::string fname = prefix + extension;
if (pcl::io::loadPLYFilepcl::PointXYZRGB(fname, *cloud) == -1) //* load the file
{
PCL_ERROR(“Couldn’t read file. \n”);
system(“PAUSE”);
return (-1);
}
std::cout << cloud->size() << endl;