学习之路(一) GDAL练习
这几天写的几个算法练习题,马上就要开始读研了,要好好努力啊!!!
言归正传,题一:gdal进行大影像二值化。控制台或者mfc对话框输入一个阈值,对灰度影像(大影像)进行二值化。
#include<stdio.h>
#include<gdal_priv.h>
#include <iostream>
using namespace std;
const int threshold=128;
int main()
{
//初始化GDAL库注册表
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //支持中文路径
//输入图像
const char* pInFile = "E:\\1_Mask.tif";
GDALDataset *pInDataSet; //文件指针
pInDataSet = (GDALDataset *)GDALOpen(pInFile, GA_ReadOnly);
if (pInDataSet == NULL)
{
cout << "文件无法打开!\n" << endl;
return 0;
}
int nWidth = pInDataSet->GetRasterXSize(); //图像宽度
int nHeight = pInDataSet->GetRasterYSize(); //图像高度
int nBands = pInDataSet->GetRasterCount(); //波段数
GDALDataType Datatype = pInDataSet->GetRasterBand(1)->GetRasterDataType(); //获取该波段的数据类型;注意GetRasterBand()是从1开始计数
cout<<"RasterXSize:"<<nWidth<<endl;
cout<<"RasterYSize:"<<nHeight<<endl;
cout<<"RasterCount:"<<nBands<<endl;
int *pBandMaps = new int[nBands];
for (int b = 0; b < nBands; b++)
pBandMaps[b] = b + 1;
unsigned char *pafScan = new unsigned char[nWidth*nHeight*nBands];
pInDataSet->RasterIO( GF_Read, 0, 0, nWidth, nHeight,
pafScan, nWidth, nHeight, Datatype, nBands, pBandMaps, 0, 0, 0);//将一个波段存入pafScan
for(int i=0;i<nWidth * nHeight;i++)
{
if(pafScan[i]<=threshold)
{
pafScan[i]=0;
}
else
{
pafScan[i]=255;
}
}
//创建输出图像、保存图像
const char* pOutFile = "E:\\OutMask.tif";
GDALDataset *pOutDataSet;
GDALDriver *pDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
if( pDriver==NULL)
{
cout << "获取创建输出图像指针poDriver失败!\n" << endl;
return 0;
}
pOutDataSet = pDriver->Create(pOutFile, nWidth, nHeight, nBands, Datatype, NULL);
pOutDataSet->RasterIO(GF_Write, 0, 0, nWidth, nHeight, pafScan, nWidth, nHeight, Datatype, nBands, pBandMaps, 0, 0, 0); //写入
GDALClose(pInDataSet);
GDALClose(pOutDataSet);
GetGDALDriverManager()->DeregisterDriver(pDriver);
GDALDestroyDriverManager();
system("pause");
return 0;
}
原始图像:
二值化图像:
关于GDAL读写主要是RasterIO这个函数吧,参考一下:https://blog.csdn.net/liminlu0314/article/details/7072224
以下内容为转载
CPLErr GDALDataset::RasterIO ( GDALRWFlag eRWFlag,
int nXOff,
int nYOff,
int nXSize,
int nYSize,
void * pData,
int nBufXSize,
int nBufYSize,
GDALDataType eBufType,
int nBandCount,
int * panBandMap,
int nPixelSpace,
int nLineSpace,
int nBandSpace
)
第一个参数RWFlag来指定是读数据还是写入数据,其值只能有两个即:GF_Read 和GF_Write,分别表示读取数据和写入数据。
第二个和第三个参数nXOff, nYOff表示读取或者写入图像数据的起始坐标图像的左上角坐标为(0,0)。
第四个和第五个参数 nXSize, nYSize表示读取或者写入图像数据的窗口大小,nXSize表示宽度,nYSize表示高度,均使用像素为单位,该宽度和高度是从第二个和第三个参数处开始计算。这两个参数和第二第三个参数一起表示就是,读取和写入图像的窗口位置和大小。
第六个参数pData是指向存储数据的一个指针。如果是写入数据,那么会将pData中的数据写入到栅格图像中去;如果是读取数据,那么会将栅格数据中的数据读入到pData中。pData的真实数据类型是通过后面的eBufType参数来指定的。如GDT_Byte就是代表的是一个8U的数据类型,如果是GDT_Float32就表示的是一个32F(float)的数据类型。RasterIO会自动将读入的数据按照参数eBufType指定的数据类型进行转换,需要注意的是,将浮点数转换为整数时,将对数据进行四舍五入处理;而且从一个大的存储单位转换到一个较小的存储单位是所进行的操作是截断操作而不是按照比例缩小操作,比如原来的实际数据中float的存取数据范围超过了缓冲数据指定的数据byte类型的最大存储范围,操作将把超过byte存储的范围外的数据进行丢弃处理,而不是将float缩小到0~255。
第七个和第八个参数nBufXSize和nBufYSize参数指定缓冲区的大小。注意pData的大小应当是nBufXSize×nBufYSize。当读取的数据是完整分辨率的数据(原始数据,没有进行缩放操作),他们应该设置和取值窗口的大小相同,也就是与第四个和第五个参数相等,但是在读取时使用了缩小或者放大系数,那么他们需要根据这个缩放系数进行调整。在这种情况下,RasterIO将会使用缩略图组overviews(金字塔)中某个合适的缩略图来进行读取数据。
第九个和第十个参数(对于GDALDataset来说还有第十一个参数nBandSpace)nPixelSpace和nLineSpace(以及nBandSpace)参数一般情况下是将0作为缺省值。但是,他们可以用于控制存取的内存数据的排列顺序,可以使用这两个参数将图像数据按照另一种组织形式读取内存缓冲区中。也就是说这两个(三个)参数可以读取或者写入非常规组织的缓冲数据。这个首先可以用于在一个缓冲区中包含多个波段数据,并且各个数据之间是交叉排列的,比如一个图像中的数据组织是RGBRGBRGB…,而普通的数据可能是RRR…GGG…BBB…,我们一般读取到的数据就是RGBRGBRGB…这种排列,现在需要使用RRR…GGG…BBB…这样的排列,一般想法就是自己写个for循环之类的,重新组织一次,其实完全没有必要,只要设置这两个(三个)参数就可以达到这个目的。
nPixelSpace表示的是在一个扫描行中一个像元的字节偏移起始点到下一个像元字节偏移起始点之间的字节间隔,如果默认使用0,那么将使用eBufType作为实际的两个像元之间的字节间隔。
nLineSpace表示在一行数据和下一行数据之间的起始字节见的间隔,如果使用0,那么将会使用eBufType*nBufXSize来表示实际间隔。
此外如果使用的GDALDataset::RasterIO函数,最后还有一个参数叫nBandSpace,同上,这个参数的意思就是一个波段与下一个波段之间的起始字节间的间隔,如果使用0,实际将使用eBufType*nBufXSize*nBufYSize来表示。
对于GDALDataset::RasterIO函数还有两个参数nBandCount和panBandMap,分别表示要读取的波段个数和波段序号,尤其是后一个参数波段序号,可以自定义先读取那一个波段,后读取那一个。
转载自:https://blog.csdn.net/baidu_33310451/article/details/81625551