(C++)GDAL学习笔记——1 均值滤波和中值滤波

2023-10-31

就要开始研究生生活了,这个暑假要学一下GDAL相关的知识,这里将中间完成的一些东西Mark下来,方便自己以后回顾。

任务

利用Vc++编写一个3*3的均值滤波或中值滤波程序

代码

注:此次试验用到的影像为波段数为1的tif格式影像

主函数:

#include<iostream>
#include "gdal.h"
#include "gdal_priv.h"
#include "Func.h"

using namespace std;

int main()
{
	// 注册、读取影像
	char* openpath = "D:\\Practice\\org\\nosieImg.tif";
	char* savepath = "D:\\Practice\\res\\nosieImg3.tif";

	GDALDataset* mDataset;		// 必要操作,定义一个gdal数据集
	GDALAllRegister();			// 必要操作,注册
	mDataset = (GDALDataset*)GDALOpen(openpath, GA_ReadOnly);	// 文件路径和打开方式
	if (mDataset == NULL)
	{
		cout << "无法打开图像" << endl;
		GDALDestroyDriverManager();		// 关闭GDAL相关的驱动
	}

	//中值滤波
	MedianFilter(mDataset);

	//均值滤波
	MeanFilter(mDataset);

	//读取完毕后需要关闭该文件,否则会内存泄漏
	GDALClose(mDataset);	

	GDALDestroyDriverManager();		// 关闭GDAL相关的驱动

	cout << "Success!!!" << endl;
	system("pause");
}

Func.cpp

#include "Func.h"

void MedianFilter(GDALDataset* Img)
{
	// 获取影像的参数
	int mXsize = Img->GetRasterXSize();
	int mYsize = Img->GetRasterYSize();
	int mBandNum = Img->GetRasterCount();
	GDALDataType mDataType = Img->GetRasterBand(1)->GetRasterDataType();

	// 申请缓冲区,OldBuf 用来保存从影像中读取的数据,NewBuf写入滤波后的数据
	unsigned char* OldBuf = new unsigned char[mXsize*mYsize*mDataType];
	unsigned char* NewBuf = new unsigned char[mXsize*mYsize*mDataType];

	// 将影像的一个波段取出,此处使用的影像只有一个波段
	GDALRasterBand* mBand1 = Img->GetRasterBand(1);

	// 将波段中的数据写到OldBuf中
	mBand1->RasterIO(GF_Read, 0, 0, mXsize, mYsize, OldBuf, mXsize, mYsize, mDataType, 0, 0);
   /*
	* RasterIO函数:
	* 参数1:读写标记。如果为GF_Read,则是将影像内容写入内存,如果为GF_Write,则是将内存中内容写入文件。
	* 参数2、3:读写开始位置。相对于图像左上角顶点(从零开始)的行列偏移量。
	* 参数4、5:要读写的块在x方向的象素个数和y方向的象素列数。
	* 参数6:指向目标缓冲区的指针,由用户分配。
	* 参数7、8:目标块在x方向上和y方向上的大小。
	* 参数9:目标缓冲区的数据类型,原类型会自动转换为目标类型。。
	* 参数10:X方向上两个相邻象素之间的字节偏移,默认为0。
	* 参数11:y方向上相邻两行之间的字节偏移, 默认为0。
	*/

	/*****************中值滤波实现*****************************/
	for (int i = 0; i < mYsize; i++)		//给最外层赋值
	{
		for (int j = 0; j < mXsize; j++)
		{
			if (i == 0 || j == 0 || i == mXsize - 1 || j == mYsize - 1)
			{
				NewBuf[i*mXsize + j] = OldBuf[i*mXsize + j];
			}
		}
	}

	int temp[9] = {0};
	for (int i = 1; i < mYsize - 1; i++)		// 最外层一圈的像素不做处理
	{
		for (int j = 1; j < mXsize - 1; j++)
		{
			temp[0] = (int)OldBuf[(i - 1)*mXsize + j - 1];
			temp[1] = (int)OldBuf[(i - 1)*mXsize + j];
			temp[2] = (int)OldBuf[(i - 1)*mXsize + j + 1];

			temp[3] = (int)OldBuf[i*mXsize + j - 1];
			temp[4] = (int)OldBuf[i*mXsize + j];
			temp[5] = (int)OldBuf[i*mXsize + j + 1];

			temp[6] = (int)OldBuf[(i + 1)*mXsize + j - 1];
			temp[7] = (int)OldBuf[(i + 1)*mXsize + j];
			temp[8] = (int)OldBuf[(i + 1)*mXsize + j + 1];

			sort(temp, temp + 9);

			NewBuf[i*mXsize + j] = (unsigned char)temp[4];
		}
	}

	/**********************分割线***********************************/

	// 新建一个驱动,影像格式为GTiff
	GDALDriver* hDriver = GetGDALDriverManager()->GetDriverByName("GTiff");

	// 创建一个输出的数据集
	char savepath[] = "D:\\Practice\\res\\MedianFilter.tif";
	GDALDataset* outDstDS = hDriver->Create(savepath, mXsize, mYsize, 1, mDataType, NULL);

	// 将NewBuf写到输出数据集中
	outDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, mXsize, mYsize, NewBuf, mXsize, mYsize, mDataType, 0, 0);

	// 释放建立的指针,释放内存
	delete[] OldBuf, NewBuf;
	GDALClose(outDstDS);
}


void MeanFilter(GDALDataset* Img)
{
	// 获取影像的参数
	int mXsize = Img->GetRasterXSize();
	int mYsize = Img->GetRasterYSize();
	int mBandNum = Img->GetRasterCount();
	GDALDataType mDataType = Img->GetRasterBand(1)->GetRasterDataType();

	// 申请缓冲区,OldBuf 用来保存从影像中读取的数据,NewBuf写入滤波后的数据
	unsigned char* OldBuf = new unsigned char[mXsize*mYsize*mDataType];
	unsigned char* NewBuf = new unsigned char[mXsize*mYsize*mDataType];

	// 将影像的一个波段取出,此处使用的影像只有一个波段
	GDALRasterBand* mBand1 = Img->GetRasterBand(1);

	// 将波段中的数据写到OldBuf中
	mBand1->RasterIO(GF_Read, 0, 0, mXsize, mYsize, OldBuf, mXsize, mYsize, mDataType, 0, 0);


	/*****************均值滤波实现*****************************/
	for (int i = 0; i < mYsize; i++)		//给最外层赋值
	{
		for (int j = 0; j < mXsize; j++)
		{
			if (i == 0 || j == 0 || i == mXsize - 1 || j == mYsize - 1)
			{
				NewBuf[i*mXsize + j] = OldBuf[i*mXsize + j];
			}
		}
	}

	int temp[9] = { 0 };
	for (int i = 1; i < mYsize - 1; i++)		// 最外层一圈的像素不做处理
	{
		for (int j = 1; j < mXsize - 1; j++)
		{
			temp[0] = (int)OldBuf[(i - 1)*mXsize + j - 1];
			temp[1] = (int)OldBuf[(i - 1)*mXsize + j];
			temp[2] = (int)OldBuf[(i - 1)*mXsize + j + 1];

			temp[3] = (int)OldBuf[i*mXsize + j - 1];
			temp[4] = (int)OldBuf[i*mXsize + j];
			temp[5] = (int)OldBuf[i*mXsize + j + 1];

			temp[6] = (int)OldBuf[(i + 1)*mXsize + j - 1];
			temp[7] = (int)OldBuf[(i + 1)*mXsize + j];
			temp[8] = (int)OldBuf[(i + 1)*mXsize + j + 1];

			double sum = temp[0] + temp[1] + temp[2] + temp[3] + temp[4] + temp[5] + temp[6] + temp[7] + temp[8];
			double ave = sum / 9;

			NewBuf[i*mXsize + j] = (unsigned char)ave;
		}
	}

	/**********************分割线***********************************/

	// 新建一个驱动,影像格式为GTiff
	GDALDriver* hDriver = GetGDALDriverManager()->GetDriverByName("GTiff");

	// 创建一个输出的数据集
	char savepath[] = "D:\\Practice\\res\\MeanFilter.tif";
	GDALDataset* outDstDS = hDriver->Create(savepath, mXsize, mYsize, 1, mDataType, NULL);

	// 将NewBuf写到输出数据集中
	outDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, mXsize, mYsize, NewBuf, mXsize, mYsize, mDataType, 0, 0);

	// 释放建立的指针,释放内存
	delete[] OldBuf, NewBuf;
	GDALClose(outDstDS);
}

运行结果

原图
原图
中值滤波结果:
在这里插入图片描述
均值滤波结果:
在这里插入图片描述

结语

过去一年忙着考研的事,确实很久没有碰C代码了,在这次学习过程中也是看着师兄的代码,查着CSDN过来的。我深知看代码不是个轻松活,所以注释写的比较多,当然由于知识有限,也是初次使用GDAL,代码和注释可能有错误的地方,也欢迎交流和指正。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(C++)GDAL学习笔记——1 均值滤波和中值滤波 的相关文章

随机推荐

  • c++自定义sort()函数的排序方法

    1 引言 在C 中 sort 函数常常用来对容器内的元素进行排序 先来了解一下sort 函数 sort 函数有三个参数 第一个是要排序的容器的起始迭代器 第二个是要排序的容器的结束迭代器 第三个参数是排序的方法 是可选的参数 默认的排序方法
  • Spring/Spring boot中静态变量赋值

    情形1 静态变量为自动注入的对象 解决方案 设置两个变量 非静态变量使用 resource注入Bean 然后使用 PostConstruct在Spring初始化Bean成功后为静态变量赋值 Component public class XX
  • sql语句直接执行很快,java程序执行慢

    一次线上Case 一条联合查询语句 直接在sql server查询分析器执行 1秒以内 通过java程序执行很慢要7秒返回结果 贴出sql 语句 select temp id temp userId temp operationUserId
  • 紫枫术河 imx6 uboot的mtd分区总结(rootfs为ubi文件系统) imx6 uboot的mtd分区总结(rootfs为ubi文件系统)

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net qq 29729577 article details 51130209 此文章基于U Boot 2014 04版本 烧写工具为mfgtool 开发
  • 蓝桥杯每日一题(18):李白打酒(python)

    Topic 话说大诗人李白 一生好饮 幸好他从不开车 一天 他提着酒壶 从家里出来 酒壶中有酒2斗 他边走边唱 无事街上走 提壶去打酒 逢店加一倍 遇花喝一斗 这一路上 他一共遇到店5次 遇到花10次 已知最后一次遇到的是花 他正好把酒喝光
  • ecshop中ajax的调用原理 1

    ecshop中ajax的调用原理 1 首先ecshop是如何定义ajax对象的 ecshop中的ajax对象是在js transport js文件中定义的 里面是ajax对象文件 声明了一个var Ajax Transport 对象和一个方
  • 大坝安全监测有哪些监测项目

    大坝安全监测有 工程主体结构 地基基础 两岸边坡 相关设施以及周围环境所作的测量及观察 也包括对建筑物外表及内部大范围对象的定期或不定期的直观检查和仪器探查 通过观测仪器和设备 以及时取得反映大坝和基岩性态变化以及环境对大坝作用的各种数据的
  • centos6.5搭建贴吧云签到平台(多图预警)

    前提 我已经用oneinstack服务搭建好了主机环境LNAMP Linux NginxApache Mysql php 默认目录是 data wwwroot default 详细步骤 1 先下载要安装的文件 我用的是GitHub上star
  • 虚拟机vmware安装win10提示operating system not found解决办法

    首先如果启动提示进入BIOS 则删除下述文件的efi 首先先设置启动PE镜像 加载启动盘PE ISO后进入PE 将系统镜像复制到U盘 PE里先分区 然后再安装 PE里安装完后重启 后面的步骤按自动的即可
  • postman循坏调用接口

    postman循坏调用接口 新建一个Collections 在新建的Collections里面新建需要循环的接口 将需要循坏变化的参数设置成变量 设置好变量之后 运行整个collections 变量值的数量应该与迭代次数一致 可以导入jso
  • YOLOv5+单目测距(python)

    YOLOv5 单目测距 python 1 相关配置 2 测距原理 3 相机标定 3 1 标定方法1 3 2 标定方法2 4 相机测距 4 1 测距添加 4 2 细节修改 可忽略 4 3 主代码 5 实验效果 相关链接 1 YOLOV7 单目
  • python ttk Treeview的插入、清空、各种点击事件、获取条目值、标题单击排序

    昨天整了一天Tkinter的treeview 发现中文的教程乃至提问都很少 其中两个问题的解决都是靠steakoverflow上找到的 在这里放出来我遇到并解决的问题 大家以后可能遇到的话就能省点事了 插入方法 import tkinter
  • 第二章-Kali安装

    目录 2 Kali Linux安装 硬盘安装 虚拟机安装 01硬盘安装 02DOCKER 03虚拟机安装 3 Kali Linux 安装 持久加密USB安装 熟悉环境 熟悉BASH命令 01 持久加密USB安装 1 02 持久加密USB安装
  • 专注于开源技术的研究与应用由Tencent://Message协议想到的一个解决方案

    源代码下载 http files cnblogs com phinecos HelloWorldProtocal rar 前天在BruceZhang 的一篇博文 求助 如何在ASP页面中调用Winform程序呢 中回答了他提出的问题 但细想
  • jsp调用证书类ocx控件问题

    1 先注册ocx 本次使用的方式是先将我调用的两个控件打包成 CAB文件 然后做成一个exe让用户去下载注册 2 jsp页面上使用 进行调用 ps clsid可以在注册表中找到 id是自己定义的 因为控件在第一步已经注册到注册表里 code
  • 重学Elasticsearch7(来源官方文档)

    一 开篇总览 1 bulk操作最好请求体数据大小在5m 15m 2 由于要给文件系统缓存留下足够空间 es的jvm堆大小不要超过服务器可用内存空间的一半 二 聚合 1 在聚合时 missing字段可以给没有该字段的文档以默认值 2 带权重的
  • html登录页面整理

    img src data image png base64 iVBORw0KGgoAAAANSUhEUgAAAycAAAJGCAYAAABBdvriAAAgAElEQVR4Aey9W5okN5KsWUz2qmaxs7zzNEvoSo78Ii
  • java自动化测试语言高级之Java 9 新特性

    java自动化测试语言高级之Java 9 新特性 文章目录 java自动化测试语言高级之Java 9 新特性 Java 9 新特性 Java 9 新特性 Java 9 发布于 2017 年 9 月 22 日 带来了很多新特性 其中最主要的变
  • 内嵌模式搭建Hive

    在此之前已经搭建好了一个三台机器的hadoop集群 https blog csdn net QYHuiiQ article details 123055389 spm 1001 2014 3001 5501 接下来在此基础上搭建hive 下
  • (C++)GDAL学习笔记——1 均值滤波和中值滤波

    就要开始研究生生活了 这个暑假要学一下GDAL相关的知识 这里将中间完成的一些东西Mark下来 方便自己以后回顾 任务 利用Vc 编写一个3 3的均值滤波或中值滤波程序 代码 注 此次试验用到的影像为波段数为1的tif格式影像 主函数 in