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(字節)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM