从上一节中我们得到了8个PCD文件,其中第一个文件是地面点云,第二个文件是地面+盒子的点云,后面的文件是6个不同角度的地面+盒子+奶牛的点云。
这一节我们将生成6个不同角度的去除了地面的点云,并计算其法向量,同时获取一些信息,用作下一节来处理。
首先,我们有8个PCD文件:
const int numberOfViews = 8;//点云数量
然后加载这8个文件:
std::vector<PCD, Eigen::aligned_allocator<PCD> > data; //点云数据
std::string prefix("cow");
std::string extension(".pcd"); //声明并初始化string类型变量extension,表示文件后缀名
// 通过遍历文件名,读取pcd文件
for (int i = 0; i < numberOfViews; i++) //遍历所有的文件名
{
std::string fname = prefix + num2str(i) + extension;
// 读取点云,并保存到models
PCD m;
m.f_name = fname;
if (pcl::io::loadPCDFile(fname, *m.cloud) == -1) //* 读入PCD格式的文件,如果文件不存在,返回-1
{
cout << "Couldn't read file " + fname + "." << endl; //文件不存在时,返回错误,终止程序。
return (-1);
}
data.push_back(m);
}
下一步,先对第一个PCD文件(即地面点云)进行离群点过滤:
for (int i = 0; i <= 1; ++i){
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
outrem.setInputCloud(data[i].cloud);
outrem.setRadiusSearch(0.01);
outrem.setMinNeighborsInRadius(10);
outrem.filter(*data[i].cloud);
}
上面这一步要一定要执行。因为Kinect得到的点云噪声很大,看起来只有地面点云,实际上某些地方(如地面上方)会出现噪点。搜索半径设置为0.01米,最小临域点云个数设置为10个点云。
下一步,单独分别对第一个和第二个文件提取其最大Y值yMax1和yMax2,并以文本的方式进行保存。原因见第一节,这里不再叙述:
float yMax1 = -1000;
for (int i = 0; i < data[0].cloud->size(); ++i)
{
if (data[0].cloud->points[i].y>yMax1)
yMax1 = data[0].cloud->points[i].y;
}
cout << "yMax1:" << yMax1 << endl;
float yMax2