GDAL的RASTERIO功能

为了能快速的显示大影像,最近一直在学习GDAL,GDAL确实是一个功能强大的开源库,其核心部分数据集和波段,下面这个图很详细的描述了它们之间的关系,还有其中的细节:

     GDAL的RASTERIO功能非常强大,简短的一句话就能实现图像的显示,但也是这个简单函数,把我折腾的半死。在学习使用GDAL的过程中,非常感谢李林大哥和貟建明大哥,他们不厌其烦地解答我的疑问,提示关键性要点,使我在解决问题的过程中事半功倍。
      我现在要把最近学习过程中的心得写下来,留给自己以后看看,也希望可以给新手们一点帮助!

GDALAllRegister();    
const char*    str ;
    
m_pDataset = (GDALDataset*) GDALOpen( str, GA_ReadOnly );

这一部分应该很好理解,首先打开一个影像,我们必须注册其驱动,因为每种不同的栅格数据都有不同的驱动,也就是driver。之后我们就可以用GDALOpen()函数来打开一个数据集dataset,如果打开的格式并不是GDAL支持的,我们就需要通过new GDALDriver()创建一个新的driver并设置,这样才能打开。如果GDALOpen()函数返回NULL,表示打开文件失败。
    打开了一个dataset之后,我们就可以对dataset的内部信息进行操作,dtaset的详细信息以及内部的关系在上图表述的非常详细。

m_pDataset->GetGeoTransform( m_AdfGeoTransform );

上面这行代码是用来获取仿射信息用的,m_AdfGeoTransform是一个含6个元素的数组,执行了这行代码后,我们就可以获取m_AdfGeoTransform数组的信息,m_AdfGeoTransform[0],m_AdfGeoTransform[3]是整个影像的坐下角坐标,m_AdfGeoTransform[1]是影像宽度上的分辨率,m_AdfGeoTransform[5]是影像高度上的分辨率,而对于m_AdfGeoTransform[2]和m_AdfGeoTransform[4]来说,如果影像是指北的,这两个参数的值为0。有了这几个参数,我们就能通过以下两行代码求出影像左下角和右上角的信息:

XMin = m_AdfGeoTransform[0];
YMin = m_AdfGeoTransform[3];

XMax = m_AdfGeoTransform[0] + nX * m_AdfGeoTransform[1] + m_AdfGeoTransform[2]; 
YMax = m_AdfGeoTransform[3] + m_AdfGeoTransform[4] + nY * m_AdfGeoTransform[5];

有了影像的信息之后,我们要做的就是将影像显示出来,这里就有一个分辨率的问题,一个是图像分辨率,一个是显示分辨率。图像分辨率就是单位长度内的像素数,而显示分辨率就是把数字图像在输出设备(比如显示屏或打印机等)上能够显示的像素数目和所显示像素之间的点距。这两个分辨率在显示影像的时候非常有作用。弄清楚原理的东西确实是成功的基石!
    然后就到了GDAL的核心部分了:

pBuffer = (BYTE*) CPLMalloc(sizeof(BYTE)*(xBuf)*(yBuf)*nBand);

m_pDataset->RasterIO( GF_Read, xSrc, ySrc, xWidth, yHight, pBuffer, xBuf, yBuf,GDT_Byte, nBand, NULL, nBand, 0, 1 );

对于三个波段以上的影像,我们可以直接通过以上两行代码讲影像读入pBuffer这个内存,然后根据我们的需要,比如说OPENGL,我们就可以利用glDrawPixels( )这个函数直接显示出影像了。现在关键的地方就是RasterIO里面的几个参数了,对照GDAL官方的函数说明:

GDALDataset::RasterIO  (  GDALRWFlag  eRWFlag,  
        int  nXOff,  
        int  nYOff,  
        int  nXSize,  
        int  nYSize,  
        void *  pData,  
        int  nBufXSize,  
        int  nBufYSize,  
        GDALDataType  eBufType,  
        int  nBandCount,  
        int *  panBandMap,  
        int  nPixelSpace,  
        int  nLineSpace,  
        int  nBandSpace 
 )  

如果为GF_Read,则是将影像内容写入内存,如果为GF_Write,则是将内存中内容写入文件。
nXOff,nYOff,nXSize,nYSize这四个参数是用于影像的,nXOff,nYOff就是说我们要从影像的这个像素坐标开始取数据,nXSize,nYSize就是从影像上取数据的宽度和高度,也就是说要从影像上取出来的数据范围是(nXOff,nYOff)到(nXOff+nXSize,nYOff+nYSize)。如果我们要显示这个取出来的范围,我们就要把这个数据域写入缓存pData中,nBufXSize,nBufYSize即是这个缓存区的大小范围。
       RasterIO这个函数只有这些说明,那我们在应用的时候就需要根据我们的实际需要计算,如果有一幅100M的影像,你想快速显示,那么这六个参数的设置就是关键,不过有一个前提条件就是这个影像是金字塔影像,这样你设置好了buffer的size,那么GDAL就会根据GDAL内部函数的实现过程,自动帮你完成缩放操作(把nXSize,nYSizen的数据缩放到BufXSize,nBufYSize的buffer里显示),而并不需要你去控制获取哪个overview,由于开始我并没有理解透这个函数的真正含义,在大影像的显示上走了很多弯路,自己去判断要读金字塔的第几层,以至于自己都把自己快搞崩溃了,这里要非常感谢李林大哥,呵呵,每个细节都给我讲的很详细,并且对于一些抽象的东西他也耐心的给我举些例子,加上自己的时间,最后终于明白了这个函数的原理所在。呵呵,在这里要真挚的感谢李大哥。 
       nBufXSize,nBufYSize这个缓存区的大小范围,决定了我们要在多大的屏幕范围显示你想显示的图像内容,因此我们要根据屏幕范围和缩放比例来计算这个buffer的size。
      nPixelSpace表示一个像素所占byte大小,假如是24位的,那么一个像素就占3个字节,那么nPixelSpace =  3。nLineSpace表示一行所占大小,如果设为0的话,就默认为nBufXSize*nBufYSize。
nBandSpace为一个波段数据所占大小,如果设为0的话,就是以RRRGGGBBB这种形式存储,如果设为1的话,就是以RGBRGBRGB这种形式存储。
    不过这个函数还是要自己试了才知道真正的意义,呵呵,希望新手少走我的弯路!!以后还会陆续添加自己的学习心得的,^_^Fighting!!!o(∩_∩)o...

分类: 编程相关

时间: 2024-12-09 01:33:12

GDAL的RASTERIO功能的相关文章

gdal读写图像分块处理(精华版)

一.gdal进行数据操作在安装好gdal后,即可调用gdal库中的函数.(需要包含的头文件:gdal_priv.h)1.打开数据集使用gdal库进行数据(影像)操作的第一步就是打开一个数据集.对于“数据集”这个名词大家可能不会太习惯,但是对于一般的格式来说,一个“数据集”就是一个文件,比如一个TIFF文件就是一个以tiff为扩展名的文件.但是对于众多RS数据来说,一个数据集包含的绝对不仅仅是一个文件.对于很多RS数据,他们把一张图像分成数个图像文件,然后放在一个文件夹中,用一些额外的文件来组织它

gdal读写图像分块处理

转自赵文原文 gdal读写图像分块处理(精华版) Review: 用gdal,感觉还不如直接用C++底层函数对遥感数据进行处理.因为gdal进行太多封装,如果你仅仅只是Geotif等格式进行处理,IO,遍历,转换,算法处理等操作,就别用gdal了.如果你想懒省事,那么这篇文章还是或许有些参考价值了.但是不推荐你这么做. 一.gdal进行数据操作 在安装好gdal后,即可调用gdal库中的函数. (需要包含的头文件:gdal_priv.h) 1.打开数据集 使用gdal库进行数据(影像)操作的第一

GDAL源码剖析(一)(转载)

GDAL源码剖析(一) GDAL 前言:一直在使用和研究GDAL的相关东西,发现网上对GDAL的内容倒是不少,但是很少有系统的介绍说明,以及内部的一些结构说明,基于这些原因,将本人的一些粗浅的理解放在此处,形成一个系列,暂时名为<GDAL源码剖析>(名称有点大言不惭,欢迎大家口水吐之,板砖拍之),供大家交流参考,有什么错误之处,望大家不吝指正,本系列对于GDAL的使用均是在Windows平台下,对于Linux平台下的不在此系列讨论范围之内.此外,转载本博客内容,请注明出处,强烈鄙视转载后不注明

栅格那点儿事(四E)

栅格金字塔 如果上面的部分都已经看过了,那么如何在ArcMap中更好的渲染一个栅格数据你已经知道了.可仅展示好一个栅格数据是不够的,我们还需要知道如何快速的展示一个栅格数据. 讲金字塔之前,先解释一下重采样的概念. 现如今我们有的影像数据大都是几十M到几十G不止.这样大小的栅格数据在ArcMap中是不能直接显示的.还记得我们前面举的那个例子么,一个606.903 MB的3波段8bit的栅格数据,共有15781列13442行.这个行列数已经是目前我们所使用的屏幕分辨率的10倍以上,也就是说在一个1

VS下的解决方案目录结构设置和管理

转载:http://blog.csdn.net/pl20140910/article/details/52074165 为了方便管理自己写的代码,也为了日后工作能方便的查找之前做过相同的代码,仿照某源码结构,自己建了一个解决方案,以方便管理自己的代码,这样代码迁移也比较方便,不需要每次重新配置第三方库或其它需要依赖的库.下图为整个解决方案目录结构设置: 图1 VS解决方案目录结构设置 如上图,为了方便管理,以后所有的项目都写在AllProject解决方案里,途中红色的部分表示的都是文件夹,绿色的

GDAL RasterIO字节对齐问题

由于C#版本的GDAL对无法很好的支持中文路径,导致出现很多乱码,使得程序在读取含有中文路径或者名称包含中文字符的文件时不能正常工作.因此采用C++封装需要的GDAL功能(dll),进行底层数据处理,然后采用C# winform做界面并调用封装后的dll文件. 但是在winform中调用封装后的dll文件进行图像数据读取显示的时候出现变形.断层等问题.于是到网上寻求答案,在这位同仁的http://www.cnblogs.com/Romi/archive/2012/03/29/2424073.ht

At + GDAL遥感图像基本浏览功能实现2

近期写了一个高光谱图像光谱曲线匹配的算法,想封装到软件当中方便观察效果,也便于做后期算法改进和实际应用,并且以后的算法可以直接集成上来.于是打算自己写一个基本的框架实现图像浏览的一些基本功能.在网上各种找,利用GDAL进行遥感图像显示的代码很多,但不是有问题就是写的不太清楚,不够简洁,并且大多基于MFC.经过几天的奋战,成功实现了利用Qt框架进行遥感图像显示的基本功能,于是分享出来,对自己是总结,并且希望对别人有所帮助. 开发环境:VS2010, Qt4.8.4,GDAL 1.10. 说明:这里

部分GDAL工具功能简介

主要转自http://blog.csdn.net/liminlu0314?viewmode=contents 部分GDAL工具功能简介 gdalinfo.exe 显示GDAL支持的各种栅格文件的信息. gdal_translate.exe 在不同的格式间进行转换.同时,潜在的执行了一些切割.重采样和使像素比例变化的任务. gdalwarp.exe 投影转换和投影绑定.同时也可以进行图像镶嵌.这个程序可以重新投影所支持的投影,而且如果图像("raw" with)控制信息也可以把GCPs

Linux下非root权限安装与使用GDAL库的方法

学习GDAL的话推荐两个网站. GDAL的官方文档:www.gdal.org 李民录老师的博客:http://blog.csdn.net/liminlu0314/article/category/777646 下面进入正题. 笔者的系统为RHEL4. 建议Linux的使用者习惯非root权限的操作,这是一个好习惯,在工作中会很有帮助. 首先安装GDAL依赖库PROJ.4和GEOS. PROJ.4是提供投影坐标系相关操作的库,GEOS是提供空间分析计算相关的库.都是开源的项目,可以自行Google