數字高程模型內插 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

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

代碼雖多不要貪杯~

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