点云处理,点云滤波,求点云DEM

点云处理,点云滤波,求点云DEM

##作业:点云数据预处理软件,具体功能包括:

1,数据的自适应导入;

2,统计点云的范围、中值、均值、直方图;

3,对点云进行滤波,剔除明显的错误噪声点(自己找资料,实现算法);

4,基于点云高度,给其赋予颜色(自己找资料,

5,利用滤波后的点云,内插DEM(可选,自己找资料,实现算法);

6,上述2~5功能支持将结果输出为文本文件或者其他格式文件。

要求: 1,要使用C++语言完成软件开发;
2,要有完整的类定义,实现接口与实现的相分离;
3,要有类的继承与封装;
4,要有标准的注释及规范的代码风格;
5,有能力的同学,可以设计相关的交互界面。 提交:

1,完整的代码工程;
2,作业实验报告(双面打印),内容包括:实验目的、逻辑设计、代码实现、结果分析、作业总结。

//head.h
#pragma once
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<windows.h>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<iomanip>
  struct point3D
{
    point3D();
   ~point3D();

    int id;
    int use;
    double xyz[3];
    int rgb[3];
    int Dis;

//重载point3D,使得可以用优先队列进行point3D类型的比较
    friend bool operator<(point3D a, point3D b)
    {
        return a.Dis > b.Dis;
    }
};

class Get_Filename
{
public:
//将一个LPCWSTR转换为string
std::string Lpcwstr2String(LPCWSTR list);

//新建一个对话窗口,选择文件
std::string get_path();

public:
//导入文件路径
const std::string filename = get_path().c_str();
};

 class CloudManger:public Get_Filename
{
public:

CloudManger();
~CloudManger();

public:

//打开文件,点云的自适应导入
void open_file();

//点云滤波,并导出滤波文件
void point_filter();

//求范围,中值,均值,直方图,并输出相应的
void point_Manger();

//给点云赋颜色,并保存到D:\\point_Cloud_rgb.txt
void point_rgb();

//求DEM并保存到D:\\DEM.txt
void DEM_Grid();

public:

//保存原始点云
std::vector<point3D>point_3D;

//存滤波后的点云
std::vector<point3D> point3D_filter;

 public:
//保存点云的x,y,z最大,最小值
double Max_x, Max_y, Max_z;
double Min_x, Min_y, Min_z;
};

//head.cpp
#include"head.h"
#define cell  100//大网格的边长
#define cell_  5//DEM网格的边长

point3D::point3D()
{
id = 0;
use = 0;
xyz[0] = 0; xyz[1] = 0; xyz[2] = 0;
rgb[0] = 0; rgb[1] = 0; rgb[2] = 0;
Dis = 0;
}
point3D::~point3D()
{
}

//将一个LPCWSTR转换为string
std::string Get_Filename::Lpcwstr2String(LPCWSTR list)
 {
	int len = WideCharToMultiByte(CP_ACP, 0, list, -1, NULL, 0, NULL, NULL);
	if (len <= 0) {
	return "";
}
else {
	char* dest = new char[len];
	WideCharToMultiByte(CP_ACP, 0, list, -1, dest, len, NULL, NULL);
	dest[len - 1] = 0;
	std::string str(dest);
	delete[] dest;
	return str;
}
}

//新建一个对话窗口,选择文件
std::string Get_Filename::get_path()
{
OPENFILENAME ofn;
char szFile[300];

ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = (LPWSTR)szFile;
ofn.lpstrFile[0] = '\0';
ofn.nFilterIndex = 1;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"ALL\0*.*\0Text\0*.TXT\0";
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;

ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
std::string path_image = "";
if (GetOpenFileName(&ofn)) {
	path_image = Lpcwstr2String(ofn.lpstrFile);
	return path_image;
}
else {
	return "";
}
}

CloudManger::CloudManger()
:Max_x(0.0), Max_y(0.0), Max_z(0.0), Min_x(0.0), Min_y(0.0), Min_z(0.0)
{
 }

CloudManger::~CloudManger()
{
 }

//打开点云文,点云的自适应导入
void CloudManger::open_file()
{
point3D store;
std::ifstream OpenFile;
std::string line;
OpenFile.open(filename, std::ios::in);
if (OpenFile.fail())//文件打开失败:返回0
{
	std::cerr << "open error" << std::endl;
	exit(1);
}
while (!OpenFile.eof() /*&& !line.empty()*/)
{
	double X, Y, Z;
	X = Y = Z = -99999;
	OpenFile >> X >> Y >> Z;
	if (Z == -99999) continue;
	store.xyz[0] = X;
	store.xyz[1] = Y;
	store.xyz[2] = Z;
	store.id++;
	point_3D.push_back(store);

}
std::cout << "Original point cloud points:" << point_3D.size() << "\n";
OpenFile.close();
return;

 }

//点云滤波---统计滤波
void CloudManger::point_filter()
{
std::vector<point3D> poilt;
std::vector<double> d;
d.clear();

//取当前点与下一个点的距离为最小临近距离
//(由于点云数据量太大,求最小k临近距离所需时间复杂度O(n^2),耗时太大)
double d_x = 0, d_y = 0, d_z = 0, d_d;

for (size_t i = 0; i < point_3D.size() - 1; i++)
{
	d_x = abs(point_3D[i].xyz[0] - point_3D[i + 1].xyz[0]);
	d_y = abs(point_3D[i].xyz[1] - point_3D[i + 1].xyz[1]);
	d_z = abs(point_3D[i].xyz[2] - point_3D[i + 1].xyz[2]);
	d_d = sqrt(pow(d_x, 2) + pow(d_y, 2) + pow(d_z, 2));
	d.push_back(d_d);
}

double d_ave = 0.0, d_var = 0.0;
//距离的平均值
for (size_t m = 0; m < d.size(); m++)
{
	d_ave += d[m] / d.size();

}
//方差
for (size_t i = 0; i < d.size(); i++)
{
	d_var += pow(abs(d[i] - d_ave), 2) / (d.size() - 1);
}
d_var = sqrt(d_var);

for (size_t i = 0; i < d.size(); i++)
{
	//这里的1.4是通过调试得到的最佳过滤情况
	if (abs(d[i] - d_ave) / d_var < 1.4)
	{
		point_3D[i].use = 1;
		poilt.push_back(point_3D[i]);
	}
}

//点云高差的均值
double avg = 0.0;
std::vector<point3D>::iterator it;
for (it = poilt.begin(); it != poilt.end(); it++)
{
	avg += it->xyz[2] / poilt.size();
}
//超过一定范围的点就舍弃
for (it = poilt.begin(); it != poilt.end(); it++)
{
	if (abs(it->xyz[2] - avg - 150) < 450)
	{
		point3D Pt;
		Pt.xyz[0] = it->xyz[0];
		Pt.xyz[1] = it->xyz[1];
		Pt.xyz[2] = it->xyz[2];
		point3D_filter.push_back(Pt);
	}
}
//保存滤波后的文件到D:\\point3D_filter.txt
std::ofstream save_filter("D:\\point3D_filter.txt", std::ios::out);
if (save_filter.fail())//文件打开失败:返回0
{
	std::cerr << "open point3D_filter.txt error" << std::endl;
}
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	if (point3D_filter[i].xyz[0] != 0)
	{
		save_filter << std::setiosflags(std::ios::fixed) << std::setprecision(3)
			<< point3D_filter[i].xyz[0] << "  " << point3D_filter[i].xyz[1] <<
			"  " << point3D_filter[i].xyz[2] << std::endl;
	}
}
std::cout << "The number of filtered points:" << point3D_filter.size() << "\n";
std::cout << "Save the points filtered file to D:\\point3D_filter.txt" << std::endl;

save_filter.close();
return;
 }

//求范围,中值,均值,直方图,并输出相应的txt文件
void  CloudManger::point_Manger()
{
std::vector <double> flt_pts_x, flt_pts_y, flt_pts_z;
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	flt_pts_x.push_back(point3D_filter[i].xyz[0]);
	flt_pts_y.push_back(point3D_filter[i].xyz[1]);
	flt_pts_z.push_back(point3D_filter[i].xyz[2]);
}
sort(flt_pts_x.begin(), flt_pts_x.end());
sort(flt_pts_y.begin(), flt_pts_y.end());
sort(flt_pts_z.begin(), flt_pts_z.end());

Max_x = flt_pts_x[flt_pts_x.size() - 1];
Max_y = flt_pts_y[flt_pts_y.size() - 1];
Max_z = flt_pts_z[flt_pts_z.size() - 1];
Min_x = flt_pts_x[0];
Min_y = flt_pts_y[0];
Min_z = flt_pts_z[0];

//范围
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe range of point x:  " << Min_x << "--" << Max_x << std::endl;
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The range of point y:  " << Min_y << "--" << Max_y << std::endl;
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The range of point z:  " << Min_z << "--" << Max_z << std::endl;

//中值
if (flt_pts_x.size() % 2 != 0)

	std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe median of point x: " << flt_pts_x[flt_pts_x.size() / 2] << std::endl;

else std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe median of point x: " << (flt_pts_x[flt_pts_x.size() / 2]
		+ flt_pts_x[flt_pts_x.size() / 2 - 1]) / 2 << std::endl;
if (flt_pts_y.size() % 2 != 0)

	std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point y: " << flt_pts_y[flt_pts_y.size() / 2] << std::endl;

else std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point y: " << (flt_pts_y[flt_pts_y.size() / 2]
		+ flt_pts_y[flt_pts_y.size() / 2 - 1]) / 2 << std::endl;
if (flt_pts_z.size() % 2 != 0)

	std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point z: " << flt_pts_z[flt_pts_z.size() / 2] << std::endl;

else std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point z: " << (flt_pts_z[flt_pts_z.size() / 2]
		+ flt_pts_z[flt_pts_z.size() / 2 - 1]) / 2 << std::endl;
//均值
double avg_x = 0.0, avg_y = 0.0, avg_z = 0.0;
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	avg_x += point3D_filter[i].xyz[0] / point3D_filter.size();
	avg_y += point3D_filter[i].xyz[1] / point3D_filter.size();
	avg_z += point3D_filter[i].xyz[2] / point3D_filter.size();
}
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe mean of the point cloud x:  " << avg_x << std::endl;
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The mean of the point cloud y:  " << avg_y << std::endl;
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The mean of the point cloud z:  " << avg_z << std::endl;
//直方图
double range_x = (flt_pts_x[flt_pts_x.size() - 1] - flt_pts_x[0]) / 10;//间隔
double range_y = (flt_pts_y[flt_pts_y.size() - 1] - flt_pts_y[0]) / 10;
double range_z = (flt_pts_z[flt_pts_z.size() - 1] - flt_pts_z[0]) / 10;
int a[10] = {}, b[10] = {}, c[10] = {};//统计每个区间的点云数,a,b,c,分别对应x,y,z

//分别统计x,y,z,值在10个分段的个数
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	for (double k = flt_pts_x[0], j = 0; k < flt_pts_x[flt_pts_x.size() - 1] && j < 10; k += range_x, j++)
	{
		if ((point3D_filter[i].xyz[0] > k || point3D_filter[i].xyz[0] == k) && point3D_filter[i].xyz[0] < k + range_x)
			a[(int)j]++;
	}
	for (double k = flt_pts_y[0], j = 0; k < flt_pts_y[flt_pts_y.size() - 1] && j < 10; k += range_y, j++)
	{
		if ((point3D_filter[i].xyz[1] > k || point3D_filter[i].xyz[1] == k) && point3D_filter[i].xyz[1] < k + range_y)
			b[(int)j]++;
	}
	for (double k = flt_pts_z[0], j = 0; k < flt_pts_z[flt_pts_z.size() - 1] && j < 10; k += range_z, j++)
	{
		if ((point3D_filter[i].xyz[2] > k || point3D_filter[i].xyz[2] == k) && point3D_filter[i].xyz[2] < k + range_z)
			c[(int)j]++;
	}
}

//根据区间内点的个数按比例输出*,作为直方图高度
std::cout << "\n";
for (double i = flt_pts_x[0], j = 0; i < flt_pts_x[flt_pts_x.size() - 1] && j < 10; i += range_x, j++)
{

	std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
		<< "X:  " << i << " - " << i + range_x << "\t\t" << a[(int)j];
	for (int k = 0; k < a[(int)j] / 2500; k++)
	{
		std::cout << "*";
	}
	std::cout << std::endl;
}
std::cout << "\n";
for (double i = flt_pts_y[0], j = 0; i < flt_pts_y[flt_pts_y.size() - 1] && j < 10; i += range_y, j++)
{

	std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
		<< "Y:  " << i << " - " << i + range_y << "\t\t" << a[int(j)];
	for (int k = 0; k < a[int(j)] / 2500; k++)
	{
		std::cout << "*";
	}
	std::cout << std::endl;
}
std::cout << "\n";
for (double i = flt_pts_z[0], j = 0; i < flt_pts_z[flt_pts_z.size() - 1] && j < 10; i += range_z, j++)
{

	std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3)
		<< "Z:  " << i << " - " << i + range_z << "\t\t\t" << a[int(j)];
	for (int k = 0; k < a[int(j)] / 2500; k++)
	{
		std::cout << "*";
	}
	std::cout << std::endl;
}

//保存点的范围,中值,均值,直方图
std::ofstream save_point_Manger("D:\\point_Manger.txt", std::ios::out);
if (save_point_Manger.fail())//文件打开失败:返回0
{
	std::cerr << "open point3D_filter.txt error" << std::endl;
}
//保存范围
save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe range of point x:  " << flt_pts_x[0] << "--" << flt_pts_x[flt_pts_x.size() - 1] << std::endl;
save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The range of point y:  " << flt_pts_y[0] << "--" << flt_pts_y[flt_pts_y.size() - 1] << std::endl;

save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3) << "The range of point z:  " 
	<< flt_pts_z[0] << "--" << flt_pts_z[flt_pts_z.size() - 1] << std::endl;
//保存中值
if (flt_pts_x.size() % 2 != 0)

	save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe median of point x: " << flt_pts_x[flt_pts_x.size() / 2] << std::endl;

else save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "\nThe median of point x: " << (flt_pts_x[flt_pts_x.size() / 2]
		+ flt_pts_x[flt_pts_x.size() / 2 - 1]) / 2 << std::endl;
if (flt_pts_y.size() % 2 != 0)

	save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point y: " << flt_pts_y[flt_pts_y.size() / 2] << std::endl;

else save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point y: " << (flt_pts_y[flt_pts_y.size() / 2]
		+ flt_pts_y[flt_pts_y.size() / 2 - 1]) / 2 << std::endl;
if (flt_pts_z.size() % 2 != 0)

	save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point z: " << flt_pts_z[flt_pts_z.size() / 2] << std::endl;

else save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The median of point z: " << (flt_pts_z[flt_pts_z.size() / 2]
		+ flt_pts_z[flt_pts_z.size() / 2 - 1]) / 2 << std::endl;
//保存均值
save_point_Manger << "\n";
save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The mean of the point cloud x:  " << avg_x << std::endl;
save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The mean of the point cloud y:  " << avg_y << std::endl;
save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
	<< "The mean of the point cloud z:  " << avg_z << std::endl;
//保存直方图
save_point_Manger << "\n";
for (double i = flt_pts_x[0], j = 0; i < flt_pts_x[flt_pts_x.size() - 1] && j < 10; i += range_x, j++)
{

	save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
		<< "X:  " << i << " - " << i + range_x << "\t\t\t" << a[(int)j];
	for (int k = 0; k < a[(int)j] / 2500; k++)
	{
		save_point_Manger << "*";
	}
	save_point_Manger << std::endl;
}
save_point_Manger << "\n";
for (double i = flt_pts_y[0], j = 0; i < flt_pts_y[flt_pts_y.size() - 1] && j < 10; i += range_y, j++)
{

	save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
		<< "Y:  " << i << " - " << i + range_y << "\t\t" << a[int(j)];
	for (int k = 0; k < a[int(j)] / 2500; k++)
	{
		save_point_Manger << "*";
	}
	save_point_Manger << std::endl;
}
save_point_Manger << "\n";
for (double i = flt_pts_z[0], j = 0; i < flt_pts_z[flt_pts_z.size() - 1] && j < 10; i += range_z, j++)
{

	save_point_Manger << std::setiosflags(std::ios::fixed) << std::setprecision(3)
		<< "Z:  " << i << " - " << i + range_z << "\t\t\t\t\t" << a[int(j)];
	for (int k = 0; k < a[int(j)] / 2500; k++)
	{
		save_point_Manger << "*";
	}
	save_point_Manger << std::endl;
}
save_point_Manger.close();
std::cout << "Save point cloud range, mean, median, histogram file to D:\\point_Manger.txt" << std::endl;
}


//给点云赋颜色,并保存到D:\\point_Cloud_rgb.txt
void CloudManger::point_rgb()
{
std::vector <double>  flt_pts_z;
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	flt_pts_z.push_back(point3D_filter[i].xyz[2]);
}
sort(flt_pts_z.begin(), flt_pts_z.end());

//给点云赋四个大颜色段
double range_Z = (flt_pts_z[flt_pts_z.size() - 1] - flt_pts_z[0]) / 4;

//每个大颜色段分成256小段,分别给点云赋颜色
double range_rgb = range_Z / 256;

for (double j = flt_pts_z[0], k = 1; j < flt_pts_z[flt_pts_z.size() - 1], k < 5; j += range_Z, k++)
{
	for (size_t i = 0; i < point3D_filter.size(); i++)
	{
		for (double m = j, n = 0; m < (j + 5 * range_Z) && n < 256; m += 5 * range_rgb, n += 5)
		{
			if ((point3D_filter[i].xyz[2] > m || point3D_filter[i].xyz[2] == m)
				&& point3D_filter[i].xyz[2] < m + 5 * range_rgb)
			{
				if (k == 1)
				{
					point3D_filter[i].rgb[0] = 0;
					point3D_filter[i].rgb[1] = int(n);
					point3D_filter[i].rgb[2] = 255;
				}
				if (k == 2)
				{
					point3D_filter[i].rgb[0] = 0;
					point3D_filter[i].rgb[1] = 255;
					point3D_filter[i].rgb[2] = 255 - int(n);
				}
				if (k == 3)
				{
					point3D_filter[i].rgb[0] = int(n);
					point3D_filter[i].rgb[1] = 255;
					point3D_filter[i].rgb[2] = 0;
				}
				if (k == 4)
				{
					point3D_filter[i].rgb[0] = 255;
					point3D_filter[i].rgb[1] = 255 - int(n);
					point3D_filter[i].rgb[2] = 0;
				}
			}
		}
	}
}

std::ofstream rgb("D:\\point_Cloud_rgb.txt", std::ios::out);
if (!rgb)
{
	std::cout << "Open point_Cloud_rgb.txt error" << std::endl;
}
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	if (point3D_filter[i].xyz[0] != 0)
	{
		rgb << std::setiosflags(std::ios::fixed) << std::setprecision(3)
			<< point3D_filter[i].xyz[0] << "  " << point3D_filter[i].xyz[1]
			<< "  " << point3D_filter[i].xyz[2] << "  " << point3D_filter[i].rgb[0]
			<< "  " << point3D_filter[i].rgb[1] << "  " << point3D_filter[i].rgb[2] << std::endl;
	}
}
rgb.close();
std::cout << "Save the dot cloud color file to D:\\point_Cloud_rgb.txt" << std::endl;
 }

//求DEM
 void  CloudManger::DEM_Grid()
{
std::vector<double> point_d_s;
std::vector<std::vector<std::vector<point3D>>> grid_map;
std::vector<std::vector<int>>gridpoint_counts;

int M, N;
double Dx, Dy;
double d_x = 0.0, d_y = 0.0, d_z = 0.0, d_d = 0.0;
Dx = Max_x - Min_x;
Dy = Max_y - Min_y;

M = int(Dx / cell) + 1;
N = int(Dy / cell) + 1;

int n = M * N;

//给网格vectorgrid_map和网格中的计数容器gridpoint_counts赋网格空间
grid_map.resize(M);
gridpoint_counts.resize(M);

for (int i = 0; i < M; i++)
{
	grid_map[i].resize(N);
	gridpoint_counts[i].resize(N);

}
//先给计数的容器中每个值赋0
for (int i = 0; i < M; i++)
{
	for (int j = 0; j < N; j++)
	{
		gridpoint_counts[i][j] = 0;
	}
}

std::vector<point3D> grid_s;
grid_s.resize(n);
std::vector<int>  grid_count;
grid_count.resize(n);
std::vector<int> Index;
Index.resize(n);
for (int i = 0; i < n; i++)
{
	grid_count[i] = 0;
}
//分网格
for (size_t i = 0; i < point3D_filter.size(); i++)
{
	int xCell = int((point3D_filter[i].xyz[0] - Min_x) / cell);
	int yCell = int((point3D_filter[i].xyz[1] - Min_y) / cell);

	//把对应点放入对应的网格中
	grid_map[xCell][yCell].push_back(point3D_filter[i]);
	//为每个网格计数
	gridpoint_counts[xCell][yCell] ++;
}

double grid_x = 0.0, grid_y = 0.0, dd_x = 0.0, dd_y = 0.0, dd_pow = 0.0;
int grid_count_x = 0, grid_count_y = 0;

//DEM网格的行数与列数x,y
grid_count_x = int(Dx / cell_) + 1;
grid_count_y = int(Dy / cell_) + 1;
grid_x = Min_x;

//总的DEM网格数
int DEM_Grid_counts = grid_count_x * grid_count_y;
std::vector<std::vector<std::vector<double>>> DEM_grid_point;
//存最小的三个距离点
std::vector<std::vector<std::vector<point3D>>>nearst_3point3;
std::vector < std::vector<point3D>>dempoint;
//给DEM网格赋空间,给存三个最近点的容器赋空间
DEM_grid_point.resize(grid_count_x);
nearst_3point3.resize(grid_count_x);
dempoint.resize(grid_count_x);
for (int i = 0; i < grid_count_x; i++)
{
	DEM_grid_point[i].resize(grid_count_y);
	nearst_3point3[i].resize(grid_count_y);
}

//把DEM网格的x,y坐标赋进DEM_grid_point
for (int i = 0; i < grid_count_x; i++)
{
	grid_y = Min_y;
	for (int j = 0; j < grid_count_y; j++)
	{
		DEM_grid_point[i][j].push_back(grid_x);
		DEM_grid_point[i][j].push_back(grid_y);
		grid_y += cell_;
	}
	grid_x += cell_;
}

//大栅格是小栅格的倍数
int H = int(cell / cell_);
存最小的三个距离点
//std::vector<std::vector<std::vector<point3D>>>nearst_3point3;
//求DEM网格点坐标与大网格点的距离
for (int i = 0; i < grid_count_x; i++)
{
	for (int j = 0; j < grid_count_y; j++)
	{
		if (gridpoint_counts[int(i / H)][int(j / H)] == 0)
		{
			continue;
		}
		//把最短的三个距离的点找出
		std::priority_queue< point3D > Min_d_3;
		for (int k = 0; k < gridpoint_counts[int(i / H)][int(j / H)]; k++)
		{
			dd_x = abs(DEM_grid_point[i][j][0] - grid_map[int(i / H)][int(j / H)][k].xyz[0]);
			dd_y = abs(DEM_grid_point[i][j][1] - grid_map[int(i / H)][int(j / H)][k].xyz[1]);
			dd_pow = sqrt(pow(dd_x, 2.0) + pow(dd_y, 2.0));
			grid_map[int(i / H)][int(j / H)][k].Dis = int(dd_pow);

			//把每个距离点放入Min_d_3,排好序,求出3个小的距离点
			Min_d_3.push(grid_map[int(i / H)][int(j / H)][k]);
		}
		//nearst_3point3里面存了最小的三个距离点
		if (Min_d_3.size() < 3)
			continue;
		else
		{
			nearst_3point3[i][j].push_back(Min_d_3.top());
			Min_d_3.pop();
			nearst_3point3[i][j].push_back(Min_d_3.top());
			Min_d_3.pop();
			nearst_3point3[i][j].push_back(Min_d_3.top());
		}
	}
}

//到比较最小的三个距离值的时候了,明天要改重载
double A = 0.0, a0 = 0.0, a1 = 0.0, a2 = 0.0, x = 0.0, y = 0.0, z = Min_z - 1.0;
double z1 = 0.0, z2 = 0.0, z3 = 0.0, z4, z5, z6;
double d1 = 0.0, d2 = 0.0, d3 = 0.0;
std::ofstream save_DEM("D:\\DEM.txt", std::ios::out);
if (!save_DEM)
{
	std::cout << "Open point_Cloud_rgb.txt error" << std::endl;
}
point3D Pt;
for (int i = 0; i < grid_count_x; i++)
{
	for (int j = 0; j < grid_count_y; j++)
	{
		if (nearst_3point3[i][j].size() == 0)
		{
			x = DEM_grid_point[i][j][0];
			y = DEM_grid_point[i][j][1];
			z = Min_z - 1.0;
			Pt.xyz[0] = x;
			Pt.xyz[1] = y;
			Pt.xyz[2] = z;
			dempoint[i].push_back(Pt);
			continue;
		}
		x = DEM_grid_point[i][j][0];
		y = DEM_grid_point[i][j][1];
		z1 = nearst_3point3[i][j][0].xyz[2];
		z2 = nearst_3point3[i][j][1].xyz[2];
		z3 = nearst_3point3[i][j][2].xyz[2];
		z4 = nearst_3point3[i][j][0].xyz[2];
		z5 = nearst_3point3[i][j][0].xyz[2];
		z6 = nearst_3point3[i][j][0].xyz[2];
		d1 = nearst_3point3[i][j][0].Dis;
		d2 = nearst_3point3[i][j][1].Dis;
		d3 = nearst_3point3[i][j][2].Dis;
		z = (z1 * d1 + z2 * d2 + z3 * d3) / (d1 + d2 + d3);
		Pt.xyz[0] = x;
		Pt.xyz[1] = y;
		Pt.xyz[2] = z;

		if (!(z > Min_z && z < Max_x))
		{
			z = z1;
			Pt.xyz[2] = z;
		}
		dempoint[i].push_back(Pt);
	}
}
for (int i = 1; i < grid_count_x - 1; i++)
{
	for (int j = 1; j < grid_count_y - 1; j++)
	{
		double z = (dempoint[i - 1][j].xyz[2] + dempoint[i + 1][j].xyz[2]
			+ dempoint[i][j - 1].xyz[2] + dempoint[i][j + 1].xyz[2]) / 4;
		save_DEM << std::setiosflags(std::ios::fixed) << std::setprecision(3)
			<< dempoint[i][j].xyz[0] << "  " << dempoint[i][j].xyz[1] << "  " << z << std::endl;
	}
}
save_DEM.close();
std::cout << "Save point cloud DEM file to D : \\DEM.txt" << std::endl;
}



 //main.cpp
#include"head.h"

    int main()
{
CloudManger p;

//导入点云数据
 p.open_file();

//点云滤波并导出滤波文件D:\\point3D_filter.txt
p.point_filter();

//求范围,中值,均值,直方图,并保存到D:\\point_Manger.txt
p.point_Manger();

//给点云赋颜色,并保存到D:\\point_Cloud_rgb.txt
p.point_rgb();

//求DEM并保存到D:\\DEM.txt
p.DEM_Grid();

system("pause");
return 0;

}

点云处理,点云滤波,求点云DEM

作业:点云数据预处理软件,具体功能包括:
1,数据的自适应导入;
2,统计点云的范围、中值、均值、直方图;
3,对点云进行滤波,剔除明显的错误噪声点(自己找资料,实现算法);
4,基于点云高度,给其赋予颜色(自己找资料,实现算法);
5,利用滤波后的点云,内插DEM(可选,自己找资料,实现算法);
6,上述2~5功能支持将结果输出为文本文件或者其他格式文件。
要求:
1,要使用C++语言完成软件开发;
2,要有完整的类定义,实现接口与实现的相分离;
3,要有类的继承与封装;
4,要有标准的注释及规范的代码风格;
5,有能力的同学,可以设计相关的交互界面。
提交:
1,完整的代码工程;
2,作业实验报告(双面打印),内容包括:实验目的、逻辑设计、代码实现、结果分析、作业总结。

  • 14
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十八闲客yxg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值