点云数据简化技术C++程序实现
论文参考《逆向工程中模型重建关键技术研究》
2.1 海量数据的空间划分
海量数据处理的关键之一是算法的效率。对于没有任何附加信息的海量散乱数 据,首先就需要建立每个测点的邻近点的信息。如果每个点都与整个点集中的其它点 计算距离并比较其大小,效率将是非常低的。为此,本文提出一个空间划分策略,以 提高算法的效率。首先读入测量点集文件,将三维坐标点存入一个一维数组,同时得 到测量点集的 X、Y、Z 坐标的小、大值,从而形成一个与坐标轴平行的长方体 包围盒,包围所有的测量点集,并根据测点的数量和分布将长方体包围盒划分成 m ×n×l 个小立方体栅格。判断每个数据点所在的立方体栅格,并将数据点的序号追加 到该立方体栅格对应的线性链表中。本文用哈希表结构存放各个小立方体栅格中所包 含的数据点,哈希表通过立方体栅格在 X、Y、Z 三个方向的索引号直接定址。 设空间长方体包围盒的小坐标为:cell_orgin_x,cell_orgin_y,cell_origin_z, 长方体包围盒的大坐标为:cell_max_x,cell_max_y,cell_max_z,立方体栅格的长度为 cell_size,当前点的三维坐标值为:px,py,pz,则 小立方体栅格在三个方向的个数为:
m = (int)(cell_max_x - cell_origin_x)/cell_size;
n = (int)( cell_max_y - cell_origin_y)/cell_size; (2-1)
l = (int)( cell_max_z - cell_origin_z)/cell_size;
求该点所在小立方体栅格的哈希函数是 :
i=(int)(px-cell_origin_x)/cell_size;
j=(int)(py-cell_origin_y)/cell_size; (2-2)
k=(int)(pz-cell_origin_z)/cell_size;
i,j,k 分别为该点所在立方体的 X,Y,Z 轴方向立方体栅格的索引号。
2.2 散乱测点间邻接关系的建立(论文理论部分省略)
#include<iostream>
#include<vector>
#include<fstream>
#include<stdlib.h>
#include<math.h>
#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include <stdio.h>
#define K 12
//#define K 18
using Eigen::MatrixXd;
using Eigen::VectorXd;
using namespace Eigen;
using namespace std;
int NUM; //数据点总数
double xmax, xmin, ymax, ymin, zmax, zmin;
double cell_size = 0.005; //栅格大小
struct gridindex //立方体栅格序号
{
int i, j, k;
};
struct point //数据点信息
{
int number;
double x, y, z;
bool canceled;
int index[K]; //k临近的序号
double dist[K];
gridindex gridindex;
};
vector<point> p;
struct pad //边结点序号及距离
{
int number;
double dist;
};
pad arra[10000],b[100]; //定义27个立方体栅格里的边结点序号及距离;k邻近个点的边结点及距离
gridindex getindex(point p) //获取数据点所在立方体栅格序号
{
int i = (int)((p.x - xmin) / cell_size);
int j = (int)((p.y - ymin) / cell_size);
int k = (int)((p.z - zmin) / cell_size);
gridindex suoyin;
suoyin.i = i;
suoyin.j = j;
suoyin.k = k;
return suoyin;
}
double dist(point p0, point p1) //计算两数据点间距离
{
double dist = sqrt((p0.x - p1.x)*(p0.x - p1.x) + (p0.y - p1.y)*(p0.y - p1.y) + (p0.z - p1.z)*(p0.z - p1.z));
return dist;
}
pad *getknn(point p0) //获取测点所有K邻近边结点(序号及距离)
{
p0.gridindex = getindex(p0);
int t = 1;
int i1 = getindex(p0).i - t;
int i2 = getindex(p0).i + t;
int j1 = getindex(p0).j - t;
int j2 = getindex(p0).j + t;
int k1 = getindex(p0).k - t;
int k2 = getindex(p0).k + t;
int i = 0;
for (int n=0;n<NUM; n++) //求出27个立方体栅格里面所有的点
{
if ((getindex(p[n]).i >= i1) && (getindex(p[n]).i <= i2))
{
if ((getindex(p[n]).j >= j1) && (getindex(p[n]).j <= j2))
{
if ((getindex(p[n]).k >= k1) && (getindex(p[n]).k <=