机载LiDAR的XYZ文件数据读取及点云二维元胞数据组织

在进行机载LiDAR点云数据组织时,涉及到二维元胞数组的构建。二维元胞数组,即将点云在XOY平面上进行规则格网划分,每个格网内存储相应的点云数据,便于后续数据处理操作,如查找近邻点操作、数学形态学滤波,均涉及到点云格网化。在这里,主要介绍使用一种vector的二级指针编写数据组织函数。
整个代码如下:

 

#include<iostream>

#include<cmath>

#define PI 3.1415926

using namespace std;

#include<vector>

#include<fstream>

#include<sstream>

#include<cmath>

struct Point3D

{

double x;

double y;

double z;

 

};

 

double get_min_element(vector<double> a)

{

double temp;

double min = a[0];

for (int i = 0; i < a.size(); i++)

{

if (min>a[i])

{

temp = min;

min = a[i];

a[i] = temp;

}

}

return min;

}

 

double get_max_element(vector<double> a)

{

double temp;

double max = a[0];

for (int i = 0; i < a.size(); i++)

{

if (max < a[i])

{

temp = max;

max = a[i];

a[i] = temp;

}

}

return max;

}

 

//数据组织函数

void PointPutIntoGrid(char *str,vector<Point3D> **grid)//二级指针

{

ifstream infile(str, ios::in);

double x, y, z;

Point3D point;

char line[64];

vector<double> Xarray, Yarray;

vector<Point3D> PointCluster;

while (infile.getline(line,sizeof(line)))

{

stringstream word(line);

word >> x;

word >> y;

word >> z;

point.x = x;

point.y = y;

point.z = z;

PointCluster.push_back(point);

Xarray.push_back(x);

Yarray.push_back(y);

}

double Xmin = get_min_element(Xarray);

double Xmax = get_max_element(Xarray);

double Ymin = get_min_element(Yarray);

double Ymax = get_max_element(Yarray);

int rows = ceil((Ymax - Ymin) / 30);//行数

int columns = ceil((Xmax - Xmin) / 30);//列数

//****************************************************不要重复再分配内存空间

for (int i = 0; i < PointCluster.size(); i++)

{

int rowID = floor((PointCluster[i].y - Ymin) / 30);

int columnID = floor((PointCluster[i].x - Xmin) / 30);

grid[rowID][columnID].push_back(PointCluster[i]);

}

}

#define Value1 125

#define Value2 8

void main()

{

char *fileName = "XXX:\\.测试数据.xyz";

ifstream infile(fileName, ios::in);

double x, y, z;

Point3D point;

char line[64];

vector<double> Xarray, Yarray;

vector<Point3D> PointCluster;

while (infile.getline(line, sizeof(line)))

{

stringstream word(line);

word >> x;

word >> y;

word >> z;

point.x = x;

point.y = y;

point.z = z;

PointCluster.push_back(point);

Xarray.push_back(x);

Yarray.push_back(y);

}

double Xmin = get_min_element(Xarray);

double Xmax = get_max_element(Xarray);

double Ymin = get_min_element(Yarray);

double Ymax = get_max_element(Yarray);

int rows = ceil((Ymax - Ymin) / 30);//行数

int columns = ceil((Xmax - Xmin) / 30);//列数

//*************************************************在具体使用时,是要声明空间内存的*********************************

vector<Point3D>**arr = new vector<Point3D>*[rows];

for (int i = 0; i < rows; i++)

{

arr[i] = new vector<Point3D>[columns];

}

PointPutIntoGrid(fileName, arr);
        
cout << "在格网" << Value1 << "行" << "," << Value1 << "列中包含的点如下:" << endl;

for (int i = 0; i < arr[Value1][Value2].size(); i++)

{

cout << "第" << i << "个点坐标:" << "X:" << arr[Value1][Value2][i].x << "\t" <<

"Y:" << arr[Value1][Value2][i].y << "\t" << "Z:" << arr[Value1][Value2][i].z << endl;

}

system("pause");

}
最后运行效果如下所示:

机载LiDAR的XYZ文件数据读取及点云二维元胞数据组织

特别注意:
在进行编写点云数据组织函数时,不要再次重新分配内存,否则会报错。但是在main()函数中,则是需要对函数指针进行内存分配的。