gdal读取正射影像数据
gdal 读取tif文件,与opencv操作图像的思路不一样,不能照搬,切不可逐个像素的调用 RasterIO 函数,操作非常耗时,最简单的方式就是全部读取,再逐个赋值。
以下是经过反复测试后的代码,可以供大家借鉴:
GDALAllRegister(); // 注册数据集
GDALDataset *poDataset; // 创建数据集
poDataset = (GDALDataset *)GDALOpen(orthoFile, GA_ReadOnly); // 打开影像
if (poDataset == NULL)
{
emit sendMsg(tr("Error: Can't open photo!\t") + orthoFile);
continue;
}
int orthoWidth = poDataset->GetRasterXSize(); // 获取影像宽度和高度
int orthoHeight = poDataset->GetRasterYSize();
double adfGeoTransform[6];
poDataset->GetGeoTransform(adfGeoTransform); // 获取影像坐标信息
if (fabs(adfGeoTransform[0]) < 1 || fabs(adfGeoTransform[3]) < 1) // 如果影像中未记录坐标系,则查找tfw文件,如果也不存在,终止程序
{
QString tfwFileName = QFileInfo(orthoList[j]).baseName() + ".tfw";
if (!QFileInfo(tfwFileName).exists())
{
return 1;
}
FILE *fp;
fopen_s(&fp, tfwFileName.toLocal8Bit().data(), "r");
if (!fp)
{
return 1;
}
int n = 0;
double tfwData[6];
while (!feof(fp))
{
char line[128];
if (!fgets(line, 128, fp))
{
break;
}
sscanf(line, "%lf", &tfwData[n++]);
if (n >= 6)
{
break;
}
}
adfGeoTransform[0] = tfwData[4];
adfGeoTransform[1] = tfwData[0];
adfGeoTransform[2] = tfwData[1];
adfGeoTransform[3] = tfwData[5];
adfGeoTransform[4] = tfwData[2];
adfGeoTransform[5] = tfwData[3];
fclose(fp);
}
int bandCount = poDataset->GetRasterCount(); // 获取波段数
GDALRasterBand *band = poDataset->GetRasterBand(1); // 获取第一个波段数据:目的是用来获取数据类型及数据宽度
GDALDataType datatype = band->GetRasterDataType(); // 获取数据类型
if (datatype == 0 || datatype == 12 || bandCount < 3) // 如类型未定义及波段数据小于3则退出
{
emit sendMsg(tr("Error: The file is error!") + orthoList[j]);
return 1;
}
int nXBuffSize = orthoWidth; // 读取缓存的宽度和高度,可根据需要对影像进行缩放
int nYBuffSize = orthoHeight;
int depth = GDALGetDataTypeSize(band->GetRasterDataType()); // 获取数据宽度
int nchar = depth / 8; // 数据类型的字节数
size_t imgBufNum = (size_t)nXBuffSize * nYBuffSize * bandCount; // 计算缓存空间大小
MEMORYSTATUS ms;
::GlobalMemoryStatus(&ms); // 获取系统内存使用情况
if (imgBufNum * 32 > ms.dwAvailPhys * 0.8) // 如果内存不够,则退出
{
emit sendMsg(tr("Error: Insufficient remaining memory, please check!"));
return 1;
}
int bandMap[3] = { 1, 2, 3 }; // 读取波段的次序,可设定,比如:RGB BGR 等
float *imgBuf = new float[imgBufNum]; // 开辟缓存空间,此处定义位float,以兼容 byte short ushort int uint
poDataset->RasterIO(GF_Read, 0, 0, orthoWidth, orthoHeight, // 获取的图像区域大小 起始坐标(x,y),宽度、高度(width,height
imgBuf, nXBuffSize, nYBuffSize, // 缓存地址,缓存的宽度和高度
GDT_Float32, // 缓存的数据类型,不是影像的数据类型,gdal会自动把影像的数据类型转为指定的数据类型
3, // 要获取的波段数,此处设为3
bandMap, // 获取的波段次序,此处设为 RGB 次序
3 * 4, // 缓存中相邻波段间隔,比如 RGB RGB,第一个R与第二个R相隔三个float,也就是 3 * 4(字节)
nXBuffSize * 3 * 4, // 缓存中相邻行的间距
4); // 缓存中两个波段的间距,R与G相邻,间隔是一个float,也就是 4(字节)

浙公网安备 33010602011771号