zoukankan      html  css  js  c++  java
  • 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!	") + 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(字节)
    

      

  • 相关阅读:
    各种排序算法java实现,好文,做个备份
    一个SQL语句
    StrutsLayout tag library 1.1发布
    “单击将本站加入收藏夹”的代码
    IE无法上网连接的解决办法
    字符问题!
    Time Tracker Starter Kit 简介
    谈恋爱是百年好合的事
    一个sql语句
    ASP.NET 中的自定义脚本回调
  • 原文地址:https://www.cnblogs.com/xingzhensun/p/11921737.html
Copyright © 2011-2022 走看看