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

本文介绍了一种通过分块读取技术优化GDAL处理大尺寸遥感影像的方法,利用RasterIO函数按行读取影像数据,显著提升了读取速度,有效改善了处理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        遥感影像小则几百兆,大则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;

}


评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

往后余生MBSE

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

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

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

打赏作者

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

抵扣说明:

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

余额充值