c++实现使用GDAL实现大幅影像的快速读取

        遥感影像小则几百兆,大则5,6GB,所以在使用GDAL进行图像读取时面临读写速度较慢的问题,我们可以深入研究gdal中RasterIO函数的机制,发现该函数是通过一行一行读取影像来实现影像读入内存的,所以我们在分块读取的时候也按照几行几行读取这样会加快读取速度,而行数可以通过我们设定的内存大小,即下面代码中的RAM_SIZE=200M来计算得到行数,这样读取速度大概可以提高19倍之多(对于5.5个GB的影像),这样的算法可以加快计算机速度,提升我们工作效率,下面是快速读取影像的代码,请读者仔细分析其中的参数的意思,加深自己的理解,学习是个不断磨炼的过程,希望大家可以耐得住寂寞,写的代码也不是很完美,大家多多指正!!!


#include "stdafx.h"

#include <stdlib.h> 
#include "gdal_priv.h"
#include <algorithm>
#include <Windows.h>
#include <stdio.h> 
#include <iostream>
using namespace std;


#define RAM_RIZE 200


void main()
{
GDALAllRegister();
GDALDataset *poDataset2;
GDALDriver*poDriver2;
//申明数据格式
const char *pszFormat2 = "Gtiff";
//驱动获取数据格式
poDriver2 = GetGDALDriverManager()->GetDriverByName(pszFormat2);
//申明写出图像路径
const char*imgPath3 = ("F:\\gdal\\data\\DOM5.tif");
//数据集poDataset2初始化,用来定义数据格式
const char *strImg = ("F:\\gdal\\data\\DOM\\ddd.tif");
GDALDataset *ImgBef = (GDALDataset*)GDALOpen(strImg, GA_ReadOnly);
if (ImgBef == NULL)
{
printf("Open Img Failed:\n%s\n", strImg);

}
int nCols = ImgBef->GetRasterXSize();         //获取影像信息
int nRows = ImgBef->GetRasterYSize();
int nBands = ImgBef->GetRasterCount();
GDALDataType gBand = ImgBef->GetRasterBand(1)->GetRasterDataType();
int nBits = GDALGetDataTypeSize(gBand);


double GeoTransform[6];                      //获取坐标信息
ImgBef->GetGeoTransform(GeoTransform);
const char *sProRef = ImgBef->GetProjectionRef(); //获取投影信息


int nStepSize = (RAM_RIZE * 1024 * 1024) / (nCols*nBands);
int nStepNum = nRows / nStepSize; if (nRows%nStepSize) nStepNum++;
int *pBand = new int[nBands]; for (int gi = 0; gi<nBands; gi++) { pBand[gi] = gi + 1; }
int isize = GDALGetDataTypeSize(GDT_UInt16) / 8;
double nodata;
nodata = ImgBef->GetRasterBand(1)->GetNoDataValue();
poDataset2 = poDriver2->Create(imgPath3, nCols, nRows, nBands, GDT_UInt16, NULL);
for (int k = 0; k < nStepNum; k++)
{
int ybeg = max(0, min(nStepSize*k, nRows - 1));
int yend = max(0, min(nStepSize*(k + 1), nRows));
WORD *pImg = new WORD[(yend - ybeg)*nCols*nBands];       //存储开操作时输入影像
memset(pImg, 0, (yend - ybeg)*nCols*nBands*sizeof(WORD));


ImgBef->RasterIO(GF_Read, 0, ybeg, nCols, (yend - ybeg), pImg, nCols, (yend - ybeg),GDT_UInt16, nBands, pBand, isize*nBands, isize*nBands*nCols, isize);
poDataset2->RasterIO(GF_Write, 0, ybeg, nCols, (yend - ybeg), pImg, nCols, (yend - ybeg), GDT_UInt16, nBands, pBand, isize*nBands, isize*nBands*nCols, isize);
delete[]pImg; pImg = NULL;
}
poDataset2->GetRasterBand(1)->SetNoDataValue(nodata);
//设置图像坐标系
poDataset2->SetGeoTransform(GeoTransform);
//设置投影方式
poDataset2->SetProjection(sProRef);
cout << "分块成功" << endl;
delete ImgBef;
delete poDataset2;

}


  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
辐射定标是遥感影像处理的重要步骤之一,能够将遥感影像中的数字值转换为具有物理含义的辐射亮度值。gdal是一个强大的开源库,可以用于读取和处理各种遥感影像格式。下面是使用gdal实现辐射定标的步骤: 1. 导入gdal库,并打开需要辐射定标的遥感影像文件。 ``` import gdal ds = gdal.Open("image.tif") ``` 2. 获取影像的光谱反射率参数,并将其存储在一个字典中。 ``` metadata = ds.GetMetadata() refl_params = {'BAND_1': float(metadata['REFLECTANCE_MULT_BAND_1']), 'BAND_2': float(metadata['REFLECTANCE_MULT_BAND_2']), 'BAND_3': float(metadata['REFLECTANCE_MULT_BAND_3'])} ``` 3. 获取影像的辐射常数,并将其存储在一个字典中。 ``` radiance_consts = {'BAND_1': float(metadata['RADIANCE_MULT_BAND_1']), 'BAND_2': float(metadata['RADIANCE_MULT_BAND_2']), 'BAND_3': float(metadata['RADIANCE_MULT_BAND_3'])} ``` 4. 读取影像的原始波段数据。 ``` band_1 = ds.GetRasterBand(1).ReadAsArray() band_2 = ds.GetRasterBand(2).ReadAsArray() band_3 = ds.GetRasterBand(3).ReadAsArray() ``` 5. 计算辐射定标后的反射率值。具体公式为:反射率 = 原始值 * 反射率参数 + 辐射常数。 ``` radiance_refl_calib = {'BAND_1': band_1 * refl_params['BAND_1'] + radiance_consts['BAND_1'], 'BAND_2': band_2 * refl_params['BAND_2'] + radiance_consts['BAND_2'], 'BAND_3': band_3 * refl_params['BAND_3'] + radiance_consts['BAND_3']} ``` 6. 将辐射定标后的反射率值重新写入遥感影像。 ``` driver = gdal.GetDriverByName("GTiff") output_ds = driver.CreateCopy("calibrated_image.tif", ds) output_ds.GetRasterBand(1).WriteArray(radiance_refl_calib['BAND_1']) output_ds.GetRasterBand(2).WriteArray(radiance_refl_calib['BAND_2']) output_ds.GetRasterBand(3).WriteArray(radiance_refl_calib['BAND_3']) output_ds.FlushCache() output_ds = None ``` 通过以上步骤,我们可以使用gdal实现辐射定标,将遥感影像的数字值转换为具有物理含义的辐射亮度值,并保存为一个新的辐射定标后的影像文件。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往后余生MBSE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值