(C++)GDAL学习笔记--1 均值滤波和中值滤波
2021/7/4 12:51:32
本文主要是介绍(C++)GDAL学习笔记--1 均值滤波和中值滤波,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
就要开始研究生生活了,这个暑假要学一下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,代码和注释可能有错误的地方,也欢迎交流和指正。
这篇关于(C++)GDAL学习笔记--1 均值滤波和中值滤波的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-09-28pyqt 怎么打包整个项目-icode9专业技术文章分享
- 2024-09-28laravel Commands 创建带有参数的 Artisan 命令的步骤和示例-icode9专业技术文章分享
- 2024-09-28antd怎么实现渲染tiff图片-icode9专业技术文章分享
- 2024-09-28英文半角中划线和中文全角的中划线有什么区别-icode9专业技术文章分享
- 2024-09-28nvm npm 和node 他们之间有什么关系-icode9专业技术文章分享
- 2024-09-28Node Version Manager (nvm)使用教程-icode9专业技术文章分享
- 2024-09-28nvm命令太慢,是什么原因-icode9专业技术文章分享
- 2024-09-28Kotlin 如何增加、删除和修改 MutableStateFlow 中的值。-icode9专业技术文章分享
- 2024-09-28Kotlin的stateFlow.update 写法介绍-icode9专业技术文章分享
- 2024-09-28kotlin 怎么获取当前时间格式-icode9专业技术文章分享