数字高程模型内插 opencv C++ CSU

承接实验三

实验配置 C++ vs2017 opencv

实验4 数字高程模型内插

一、实验目的

  • 掌握最小二乘配置算法

二、实验内容与要求

1.DEM类设计

要求: 设计一个DEM类,包括记录DEM的原点座标、DEM格网间距、DEM格网大小、DEM高程等基本属性(DEM的格式如下表所示)。
DSAA
nx ny
nx is the integer number of grid lines along the X axis (columns)
ny is the integer number of grid lines along the Y axis (rows)
xlo xhi
xlo is the minimum X value of the grid
xhi is the maximum X value of the grid
ylo yhi
ylo is the minimum Y value of the grid
yhi is the maximum Y value of the grid
zlo zhi
zlo is the minimum Z value of the grid
zhi is the maximum Z value of the grid
grid row 1
grid row 2
grid row 3
these are the rows of Z values of the grid, organized in row order. Each row has a constant Y coordinate. Grid row 1 corresponds to ylo and the last grid row corresponds to yhi. Within each row, the Z values are arranged from xlo to xhi.

DSAA
10 10
0.0 9.0
0.0 7.0
25.00 97.19
91.03 77.21 60.55 46.67 52.73 64.05 41.19 54.99 44.30 25.00
96.04 81.10 62.38 48.74 57.50 63.27 48.67 60.81 51.78 33.63
92.10 85.05 65.09 53.01 64.44 65.64 52.53 66.54 59.29 41.33
94.04 85.63 65.56 55.32 73.18 70.88 55.35 76.27 67.20 45.78
97.19 82.00 64.21 61.97 82.99 80.34 58.55 86.28 75.02 48.75
91.36 78.73 64.05 65.60 82.58 81.37 61.16 89.09 81.36 54.87
86.31 77.58 67.71 68.50 73.37 74.84 65.35 95.55 85.92 55.76
80.88 75.56 74.35 72.47 66.93 75.49 86.39 92.10 84.41 55.00
74.77 66.02 70.29 75.16 60.56 65.56 85.07 89.81 74.53 51.69
70.00 54.19 62.27 74.51 55.95 55.42 71.21 74.63 63.14 44.99

2.设计最小二乘配置的点云格网DEM内插程序。

基于设计的DEM类,要求读入给定格式的点云数据,把剔除粗差后的点云写入到给定的文件中,再利用剔除粗差后的点内插一个均匀格网的DEM。

三、设计与实现

3.1类的设计

在这里插入图片描述

3.2控件按钮及其属性

在这里插入图片描述
在这里插入图片描述

3.3主要代码

这里仅展示涉及到相关系数法相关功能的代码。

3.3.1文件:< CDem.h >

#pragma once
#include "C_points.h"
/***************************************************************************
类:CDem
作用:封装最小二乘DEM制作操作函数,仅储存按钮操作功能,调用txt
Welcome to my Github and my CSDN blog , more information will be available about the project!
Github:https://github.com/Yiqingde
CSDN Blog:https://me.csdn.net/weixin_42348202
历史:**日期**         **理由**            **签名**
	  2019年10月26日        创建             ***
/**************************************************************************/
class CDem
{
	C_points *p;//数据对象,一维数组
	int allpoints;//所有点
	//定义行列数
	int nx;//行号
	int ny;//列号
	
	double width;//分辨率1 或3
	double dists;//距离
	//定义六个变量用来储存最大最小值
	double xlo;
	double xhi;
	double ylo;
	double yhi;
	double zlo;
	double zhi;
public:
	CDem();
	~CDem();
	int Div(const CString strLine, char split, CStringArray &strArray);//字符串分割函数
	void findpoints(int x, int y, int size, C_points *d);//寻点
	void convertxy2id(double x, double y, int &tempr, int &tempc, int &id);//转换ID
	int convertcr2id(int tempr, int tempc);//转换ID
	void convertid2rc(int id, int&rr, int &cc);//转换ID
	double dist(double x, double y, double x2, double y2);//计算距离
	double truedist2(double x, double y, double x2, double y2);//计算距离
	double workout(int rr, int cc, Mat X_six);//最小二乘矩阵
	bool readDem();//读取dem数据
	void search();//搜索函数
	void out();//输出1
	void out2();//输出2
	void out3();//输出3
	void getcolor1(Mat &f);//渐变颜色函数,矩阵
	void returncolor(double &a, double &b, double &c, double zz, double min, double max, Mat color);//得到颜色
	void BeatifulDem();//进行最后的Dem美化,去除噪声
	void main();//主函数
};

3.3.2文件:< CMatchingImg.cpp >

#include "stdafx.h"
#include "CDem.h"
typedef struct tagDIRECTION
{
	int x_offset;
	int y_offset;
}DIRECTION;

DIRECTION direction_8[] = { {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} };
//DIRECTION direction_4[] = { {0, -1},{0, 1} ,{-1, 0}, {1, 0}};
CDem::CDem()
{
	this->xlo = 9999999;
	this->ylo = 9999999;
	this->zlo = 9999999;
	this->xhi = 0;
	this->yhi = 0;
	this->zhi = 0;
	width = 3;
	dists = 10;
}


CDem::~CDem()
{
	if (p != NULL)
	{
		delete[] p;
	}
}

/***************************************************************************
函数:getcolor1(Mat &f)
作用:颜色代码
参数:Mat &f 颜色矩阵 浮点数0-1
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::getcolor1(Mat &f)
{
	f.create(64, 3, CV_64FC1);
	double temp_1 = 0.5625;
	for (int i = 0; i < 8 ;i++)
	{
		f.at<double>(i, 0) = 0;
		f.at<double>(i, 1) = 0;
		f.at<double>(i, 2) = temp_1;
		temp_1 += 0.0625;
	}
	temp_1 = 0.0625;
	for (int i = 8; i < 24; i++)
	{
		f.at<double>(i, 0) = 0;
		f.at<double>(i, 1) = temp_1;
		f.at<double>(i, 2) = 1;
		temp_1 += 0.0625;
	}
	temp_1 = 0.0625;
	for (int i = 24;  i < 40;i++)
	{
		f.at<double>(i, 0) = temp_1;
		f.at<double>(i, 1) = 1;
		f.at<double>(i, 2) = 1-temp_1;
		temp_1 += 0.0625;
	}
	temp_1 = 0.9375;
	for (int i = 40; i < 55; i++)
	{
		f.at<double>(i, 0) = 1;
		f.at<double>(i, 1) = temp_1;
		f.at<double>(i, 2) = 0;
		temp_1 -= 0.0625;
	}
	temp_1 = 1;
	for (int i = 55; i < 64;i++)
	{
		f.at<double>(i, 0) = temp_1;
		f.at<double>(i, 1) = 0;
		f.at<double>(i, 2) = 0;
		temp_1 -= 0.0625;
	}
}

/***************************************************************************
函数:returncolor(double &a, double &b, double &c, double zz, double min, double max,Mat color)
作用:由颜色矩阵获得rgb颜色,根据最大值最小值
参数:double &a  返回rgb中a
      double &b  返回rgb中b
	  double &c  返回rgb中c
	  double zz  依据该值上色
	  double min 最小值
	  double max 最大值
	  Mat color 颜色矩阵
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::returncolor(double &a, double &b, double &c, double zz, double min, double max,Mat color)
{
	int t = (zz - min) * 64 / (max - min);
	t = t < 0 ? 0 : t;
	t = t > 64 ? 64 : t;
	a = color.at<double>(t, 0);
	b = color.at<double>(t, 1);
	c = color.at<double>(t, 2);
}


//***********************************
//字符分割函数
//***********************************
int CDem::Div(const CString strLine, char split, CStringArray &strArray)
{
	strArray.RemoveAll();//自带清空属性
	CString temp = strLine;
	int tag = 0;
	while (1)
	{
		tag = temp.Find(split);
		if (tag >= 0)
		{
			strArray.Add(temp.Left(tag));
			temp = temp.Right(temp.GetLength() - tag - 1);
		}
		else { break; }
	}
	strArray.Add(temp);
	return strArray.GetSize();
}


/***************************************************************************
函数:convertcr2id(int tempr, int tempc)
作用:输入行号列号返回 id
参数:int tempr
      int tempc
返回值:int 一维数组得id号
历史:**日期**         **理由**            **签名**
	  20191027日        创建             ***
/**************************************************************************/
int CDem::convertcr2id(int tempr, int tempc)
{
	int id = (tempr - 1)*ny + tempc - 1;
	return id;
}

/***************************************************************************
函数:convertid2rc(int id, int&rr, int &cc)
作用:输入id 解求行列号
参数:int id  id号
	  int &rr  行列号
	  int &cc  行列号
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::convertid2rc(int id, int &rr, int &cc)
{
	double temp = double(id + 1) - 0.05;
	rr = (int(temp) / ny) + 1;
	cc = id + 1 - (rr - 1) *ny;
}

/***************************************************************************
函数:convertxy2id(double x, double y, int &tempr, int &tempc, int &id)
作用:输入xy   返回 解求行列号及id 塞入数组时使用
参数:double x x值
	  double y y值
	  int &tempr  行号
	  int &tempc  列号
	  int &id  id
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::convertxy2id(double x, double y, int &tempr, int &tempc, int &id)
{
	tempr = int((x - xlo-0.001) / width) + 1;
	tempc = int((y - ylo-0.001) / width) + 1;
	id=convertcr2id(tempr, tempc);
}


/***************************************************************************
函数:dist(double x, double y, double x2, double y2)
作用:求取距离
参数:double x 真xyz值
	  double y 真xyz值
	  double x2 格网点的行列号
	  double y2 格网点的行列号
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
double CDem::dist(double x, double y, double x2, double y2)
{
	x2= (x2 - 1)*width + xlo;
	y2= (y2 - 1)*width + ylo;
	double distance = sqrt((x - x2)*(x - x2) + (y - y2)*(y - y2));
	return distance;
}

/***************************************************************************
函数:dist(double x, double y, double x2, double y2)
作用:求取距离的平方
参数:double x 真xyz值
	  double y 真xyz值
	  double x2 真xyz值
	  double y2 真xyz值
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
double CDem::truedist2(double x, double y, double x2, double y2)
{
	double distance = (x - x2)*(x - x2) + (y - y2)*(y - y2);
	return distance;
}


/***************************************************************************
函数:readDem()
作用:读取Dem数据 存入p中
参数:无
返回值:bool 读1 非0
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
bool CDem::readDem()//读取dem数据
{
	CFileDialog dlgFile(TRUE, _T("txt"), NULL,
		OFN_ALLOWMULTISELECT | OFN_EXPLORER,
		//_T("(文本文件)|*.txt"));
		_T(""));
	if (dlgFile.DoModal() == IDCANCEL) return 0;
	CString strName = dlgFile.GetPathName();//获取打开文件文件名(路径)
	setlocale(LC_ALL, "");
	CStdioFile sf;
	if (!sf.Open(strName, CFile::modeRead)) return 0;//打开strName文件路径中的内容
	CString strLine;
	CString strContent;//接受内容字符串
	CStringArray array;//供下文分割使用
	strContent.Empty();//strContent中内容清空

	//开始读数据 
	BOOL bEOF = sf.ReadString(strLine);//第一行
	if (bEOF == 0) { AfxMessageBox(_T("空数据")); return 0; }
	allpoints = _ttoi(strLine);
	
	vector<Point3d> int_points_xyz;
	vector<Point3i> int_points_rgb;
	for (int i = 0; i < allpoints; i++)
	{
		bEOF = sf.ReadString(strLine);
		if (bEOF == 0) { AfxMessageBox(_T("数据不规范")); return 0; }
		int n = Div(strLine, ' ', array);
		if (n < 3) { AfxMessageBox(_T("数据缺失")); return 0; }
		C_points temp;
		temp.addxyz(int_points_xyz, _tstof(array[0]), _tstof(array[1]), _tstof(array[2]));
		temp.addrgb(int_points_rgb, _ttoi(array[3]), _ttoi(array[4]), _ttoi(array[5]));
		xlo = (xlo < _tstof(array[0])) ? xlo : _tstof(array[0]);
		xhi = (xhi > _tstof(array[0])) ? xhi : _tstof(array[0]);
		ylo = (ylo < _tstof(array[1])) ? ylo : _tstof(array[1]);
		yhi = (yhi > _tstof(array[1])) ? yhi : _tstof(array[1]);
		zlo = (zlo < _tstof(array[2])) ? zlo : _tstof(array[2]);
		zhi = (zhi > _tstof(array[2])) ? zhi : _tstof(array[2]);
	}
	//进行行和列的初始化
	if (allpoints > 100000) { width = 1; }
	const int r = (xhi - xlo ) / width+1;//行数 是x决定
	const int c = (yhi - ylo ) / width+1;//列数
	nx = r;
	ny = c;
	p = new C_points[r*c];//定义的一维数组 

	for (int i = 0; i < allpoints; i++)
	{
		int tempr, tempc,  idd = 0;
		convertxy2id(int_points_xyz.at(i).x, int_points_xyz.at(i).y, tempr, tempc, idd);
		p[idd].add_int(tempr, tempc, int_points_xyz.at(i).x, int_points_xyz.at(i).y, int_points_xyz.at(i).z, int_points_rgb.at(i).x, int_points_rgb.at(i).y, int_points_rgb.at(i).z);
	}
	for (int i = 0; i < r*c; i++)
	{
		int temp_r, temp_c;
		convertid2rc(i, temp_r, temp_c);
		p[i].row = temp_r;
		p[i].col = temp_c;
	}
	return 1;
}


/***************************************************************************
函数:findpoints(int x, int y, int size, C_points *d)
作用:寻找点位,存入d对象成员的mat矩阵
参数:int x 输入行号
	  int y 输入列号
	  int size 窗口大小
	   C_points *d 即对象
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void  CDem::findpoints(int x, int y, int size, C_points *d)
{

	int halfsize = size / 2;
	for (int i = -halfsize; i < size; i++)
	{
		for (int j =-halfsize; j < size; j++)
		{
			//窗口出界则跳过
			if (convertcr2id(x + i, y + j) > 0 && convertcr2id(x + i, y + j) < nx*ny&&(x+i)>0&& (x + i) <=nx&& (y + i) > 0 && (y + i) <= ny)
			{
				//判断该点是否有元素
				if (d[convertcr2id(x + i, y + j)].sizee != 0)
				{
					for (int ii = 0; ii < d[convertcr2id(x + i, y + j)].sizee; ii++)
					{
						//自适应增大窗口
						double temp = dist(d[convertcr2id(x + i, y + j)].xyz.at(ii).x, d[convertcr2id(x + i, y + j)].xyz.at(ii).y,x,y);
						if (temp < size*5)
						{
							d[convertcr2id(x, y)].X_six.at<double>(d[convertcr2id(x, y)].sizeee, 0) = d[convertcr2id(x + i, y + j)].xyz.at(ii).x;
							d[convertcr2id(x, y)].X_six.at<double>(d[convertcr2id(x, y)].sizeee, 1) = d[convertcr2id(x + i, y + j)].xyz.at(ii).y;
							d[convertcr2id(x, y)].X_six.at<double>(d[convertcr2id(x, y)].sizeee, 2) = d[convertcr2id(x + i, y + j)].xyz.at(ii).z;
							d[convertcr2id(x, y)].X_six.at<double>(d[convertcr2id(x, y)].sizeee, 3) = 1;
							d[convertcr2id(x, y)].rgb_r = d[convertcr2id(x + i, y + j)].rgb.at(ii).x;
							d[convertcr2id(x, y)].rgb_g = d[convertcr2id(x + i, y + j)].rgb.at(ii).y;
							d[convertcr2id(x, y)].rgb_b = d[convertcr2id(x + i, y + j)].rgb.at(ii).z;
							d[convertcr2id(x, y)].sizeee++;
						}
						if (d[convertcr2id(x, y)].sizeee == 6) { return; }
					}
				}
			}
		}
	}
}


/***************************************************************************
函数:workout(int rr, int cc, Mat X_six)
作用:最小二乘算法
参数:int rr 行号
	  int cc 列号
	  Mat X_six 矩阵
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
double CDem::workout(int rr, int cc, Mat X_six)
{
	Mat X_six_clone;//将矩阵复制
	X_six_clone = X_six.clone();	
	if (p[convertcr2id(rr, cc)].sizeee ==6)
	{
		//局部中心化
		double x_center = 0;
		double y_center = 0;
		for (int i = 0; i < X_six_clone.rows; i++)
		{
			x_center += X_six_clone.at<double>(i, 0);
			y_center += X_six_clone.at<double>(i, 1);
		}
		x_center = x_center / X_six_clone.rows;
		y_center = y_center / X_six_clone.rows;
		for (int i = 0; i < X_six_clone.rows; i++)
		{
			X_six_clone.at<double>(i, 0) = X_six_clone.at<double>(i, 0) - x_center;
			X_six_clone.at<double>(i, 1) = X_six_clone.at<double>(i, 1) - y_center;
		}
		Mat M=Mat::zeros(X_six_clone.rows,6, X_six_clone.type());
		Mat Z=Mat::zeros(X_six_clone.rows,1, X_six_clone.type());
		Mat P=Mat::zeros(X_six_clone.rows,6, X_six_clone.type());
		for (int i = 0; i < M.rows; i++)
		{
			M.at<double>(i, 0) = X_six_clone.at<double>(i, 0)*X_six_clone.at<double>(i, 0);
			M.at<double>(i, 1) = X_six_clone.at<double>(i, 0)*X_six_clone.at<double>(i, 1);
			M.at<double>(i, 2) = X_six_clone.at<double>(i, 1)*X_six_clone.at<double>(i, 1);
			M.at<double>(i, 3) = X_six_clone.at<double>(i, 0);
			M.at<double>(i, 4) = X_six_clone.at<double>(i, 1);
			M.at<double>(i, 5) = 1;
			Z.at<double>(i, 0) = X_six_clone.at<double>(i, 2);
			P.at<double>(i, i) = 1/truedist2(X_six_clone.at<double>(i, 0), X_six_clone.at<double>(i, 1), x_center, y_center);
		}
		Mat X = (M.t()*M).inv()*M.t()*Z;//最小二乘解求
		double f = X.at<double>(5, 0);
		//对于明显错误的进行加权算法
		if (f < zlo || f > zhi)
		{
			double sum = 0;
			double f = 0;
			for (int j = 0; j < p[convertcr2id(rr, cc)].sizeee; j++)
			{
				sum += X_six.at<double>(j, 3);
			}
			for (int j = 0; j < p[convertcr2id(rr, cc)].sizeee; j++)
			{
				f += X_six.at<double>(j, 3)*X_six.at<double>(j, 2);
			}
			return f / sum;
		}
		//滤波
		return f;
	}
}

/***************************************************************************
函数:search()
作用:搜索解求
参数:
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::search()
{
	for (int i = 0; i < nx*ny; i++)
	{
		int rr = 0;
		int cc = 0;
		convertid2rc(i, rr, cc);//由id得行和列
		int ddsize = 4;//其实窗口4*4
		while (1)
		{
			findpoints(rr, cc,ddsize, p);
			ddsize += 4;//找不到6个点,窗口依次增加4
			if (p[i].sizeee == 6) { break; }//找到即撤
		}
		p[i].zz = workout(rr, cc, p[i].X_six);//解求
	}
}

/***************************************************************************
函数:out()
作用:输出Dem.grd.txt
参数:
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::out()
{
	//输出至txt中
	CStdioFile SF;
	CString strLine;
	CString strOut;
	setlocale(LC_ALL, "");
	if (!SF.Open(_T("Dem.grd"), CFile::modeCreate | CFile::modeWrite)) return;
	strLine.Format(_T("%s\n%d %d\n%f %f\n%f %f\n%f %f\n"),
		"DSAA",
		nx, ny,
		xlo, xhi,
		ylo, yhi,
		zlo, zhi
	);
	strOut += strLine;

	for (int j = 1; j <= ny; j++)
	{
		for (int i = 1; i <= nx; i++)
		{
			strLine.Format(_T("%.4f "), p[convertcr2id(i, j)].zz);
			strOut += strLine;
		}
	}
	SF.WriteString(strOut);
	SF.Close();
	AfxMessageBox(_T("成功!已输入至“Dem.grd 、DemDataforCloudCompare_2color.txt、DemPecessForDebug.txt”中(在MFC工作路径)"));
}

/***************************************************************************
函数:out2()
作用:输出DemDataforCloudCompare_2color.txt,可用DemDataforCloudCompare_2color
打开两种颜色,一种渐变,一种真实
参数:
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::out2()
{
	CStdioFile SF;
	CString strLine;
	CString strOut;
	setlocale(LC_ALL, "");
	if (!SF.Open(_T("DemDataforCloudCompare_2color.txt"), CFile::modeCreate | CFile::modeWrite)) return;
	Mat colormap;
	getcolor1(colormap);
	for (int i = 0; i < (nx*ny); i++)
	{

		int cc = 0; int rr = 0;
		convertid2rc(i, rr, cc);
		int i2 = convertcr2id(rr, cc);
		double x_center = (rr - 1)*width + xlo;
		double y_center = (cc - 1)*width + ylo;
		double a;
		double b;
		double c;
		returncolor(a, b, c, p[i].zz,zlo,zhi,colormap);
		strOut += strLine;
		strLine.Format(_T("%.8f %.8f %.8f %f %f %f %d %d %d\n"),
			x_center, y_center, p[i].zz,a,b,c, p[i].rgb_r, p[i].rgb_g, p[i].rgb_b
		);
		strOut += strLine;
		
	}
	SF.WriteString(strOut);
	SF.Close();
}


/***************************************************************************
函数:out3()
作用:输出DemPecessForDebug.txt
参数:
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::out3()
{
	CStdioFile SF;
	CString strLine;
	CString strOut;
	setlocale(LC_ALL, "");
	if (!SF.Open(_T("DemPecessForDebug.txt"), CFile::modeCreate | CFile::modeWrite)) return;

	for (int i = 0; i < (nx*ny); i++)
	{

		int cc = 0; int rr = 0;
		convertid2rc(i, rr, cc);
		int i2 = convertcr2id(rr, cc);
		double x_center = (rr - 1)*width + xlo;
		double y_center = (cc - 1)*width + ylo;

		strOut += strLine;
		strLine.Format(_T("%.8f %.8f %.8f \n"),
			x_center, y_center, p[i].zz
		);
		strOut += strLine;
		for (int j = 0; j < p[i].sizeee; j++)
		{
			int rr = 0;
			int cc = 0;
			int iddd = 0;
			convertxy2id(p[i].X_six.at<double>(j, 0), p[i].X_six.at<double>(j, 1), rr, cc, iddd);
			double sd = p[i].X_six.at<double>(j, 2);
			strLine.Format(_T("%.8f %.8f %.8f %d %d %d \n"),
				p[i].X_six.at<double>(j, 0), p[i].X_six.at<double>(j, 1), p[i].X_six.at<double>(j, 2), rr, cc, iddd
			);
			strOut += strLine;
		}
		strLine.Format(_T("\n"));
	}
	strOut += strLine;

	SF.WriteString(strOut);
	SF.Close();
}

/***************************************************************************
函数:BeatifulDem()
作用:除噪
参数:
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::BeatifulDem()
{
	for (int i = 1; i <= nx; i++)
	{
		for (int j = 1; j <= ny; j++)
		{
			int tag = 5;
			if (convertcr2id(i + tag, j) > 0 && convertcr2id(i - tag, j) > 0 && convertcr2id(i, j + tag) > 0 && convertcr2id(i, j - tag) > 0)
			{
				if (convertcr2id(i + tag, j) < nx*ny && convertcr2id(i - tag, j) < nx*ny  && convertcr2id(i, j + tag) < nx*ny  && convertcr2id(i, j - tag) < nx*ny)
				{
					double temp1 = fabs(p[convertcr2id(i, j)].zz - p[convertcr2id(i + tag, j)].zz);
					double temp2 = fabs(p[convertcr2id(i, j)].zz - p[convertcr2id(i - tag, j)].zz);
					double temp3 = fabs(p[convertcr2id(i, j)].zz - p[convertcr2id(i, j + tag)].zz);
					double temp4 = fabs(p[convertcr2id(i, j)].zz - p[convertcr2id(i, j - tag)].zz);
					double Dist = 5;
					double ff =  p[convertcr2id(i + tag, j)].zz+ p[convertcr2id(i - tag, j)].zz+ p[convertcr2id(i, j + tag)].zz+ p[convertcr2id(i, j - tag)].zz;
					if (temp1 > Dist&&temp2 > Dist&&temp3 > Dist&&temp4 > Dist)
					{
						p[convertcr2id(i, j)].zz = ff/4;
					}
				}
			}
		}
	}
	for (int i = 1; i <= nx; i++)
	{
		for (int j = 1; j <= ny; j++)
		{
			int tag = 5;
			if (i <= tag || i > nx - tag || j <= tag || j > ny - tag)
			{
				int t = (i - tag) > 0 ? (i - tag) : (i + tag);
				int t2 = (j - tag) > 0 ? (j - tag) : (j + tag);
				p[convertcr2id(i, j)].zz = p[convertcr2id(t, t2)].zz;

			}
		}
	}
}
/***************************************************************************
函数:main()
作用:主函数
参数:
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void CDem::main()
{
	bool tagger=readDem();//读取数据
	if (tagger == 0) { return; }
	search();//搜索
	BeatifulDem();//除噪
	out2();//输出
	out3();//输出
	out();//输出
}

3.3.3文件: < C_points.h >

#pragma once
/***************************************************************************
类:C_points
作用:存储格网点的元素
Welcome to my Github and my CSDN blog , more information will be available about the project!
Github:https://github.com/Yiqingde
CSDN Blog:https://me.csdn.net/weixin_42348202
历史:**日期**         **理由**            **签名**
	  2019年10月26日        创建             ***
/**************************************************************************/
#include <opencv2/opencv.hpp>
#include <vector>
#include <opencv2/flann/miniflann.hpp>
using namespace cv;
using namespace std;
class C_points
{
public:
	C_points();
	~C_points();
	int row;//row指的是行号  x
	int col;//col指的是列号  y
	
	double zz;//高程
	int rgb_r;//颜色
	int rgb_g;
	int rgb_b;
	vector<Point3d> xyz;//高程
	vector<Point3i> rgb;//颜色
	int sizeee;//用来给X_six计数
	int sizee;//vector的大小
	Mat X_six;//存储最小二乘需要的数据
	void addxyz(vector<Point3d> &xyz, double x, double y, double z);//加xyz
	void addrgb(vector<Point3i> &rgb, int r, int g, int b);//加颜色
	void add_int(double r, double c, double x, double y, double z, int r2, int g, int b);//加初始值
};

3.3.4文件: < C_points.cpp >

#include "stdafx.h"
#include "C_points.h"

C_points::C_points()
{
	tag = 0;
	sizee=0;
	sizeee = 0;
	X_six.create(6, 4, CV_64FC1);
	rgb_r = 0;
	rgb_g = 0;
	rgb_b = 0;
}


C_points::~C_points()
{
}
/***************************************************************************
函数:addxyz(vector<Point3d> &xyz, double x, double y, double z)
作用:xyz写入vector
参数:vector<Point3d> &xyz 存入vector数组
      double x x值
	  double y y值
	  double z z值
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void C_points::addxyz(vector<Point3d> &xyz, double x, double y, double z)
{
	Point3d temp;
	temp.x = x;
	temp.y = y;
	temp.z = z;
	sizee++;
	xyz.push_back(temp);
}
/***************************************************************************
函数:addrgb(vector<Point3i> &rgb, int r, int g, int b)
作用:rgb写入vector
参数:vector<Point3i> &rgb 存入vector数组
	  int r
	  int g
	  int b
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void C_points::addrgb(vector<Point3i> &rgb, int r, int g, int b)
{
	Point3i temp;
	temp.x = r;
	temp.y = g;
	temp.z = b;
	rgb.push_back(temp);
}
/***************************************************************************
函数:add_int(double r, double c, double x, double y, double z, int r2, int g, int b)
作用:写入综合函数
参数:double r 行号
	  double c 列号
	  double x x值
	  double y y值
	  int r2 rgb的r2
	  int g  rgb的b
	  int b  rgb的b
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月27日        创建             ***
/**************************************************************************/
void C_points::add_int(double r, double c, double x, double y, double z, int r2, int g, int b)
{
	row = r;
	col = c;
	addxyz(xyz, x, y, z);
	addrgb(rgb, r2, g, b);
}

3.3.5文件: < CBasic.cpp >(仅展示部分)

/***************************************************************************
函数:Button_DEM()
作用:DEM按钮
参数:无
返回值:无
历史:**日期**         **理由**            **签名**
	  2019年10月6日        创建             ***
/**************************************************************************/
void CBasic::Button_DEM()
{
	CDem t;
	t.main();
}

3.3.6文件: < ZRX0107170110Dlg.cpp >(仅展示部分)

void CZRX0107170110Dlg::OnBnClickedread7()
{
	// TODO: 在此添加控件通知处理程序代码
	CBasic tt;
	tt.Button_DEM();
}

3.4运行结果

3.4.1采用uav1m.txt

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.2采用uav3m.txt

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码虽多不要贪杯~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章