• GDAL RasterIO读取波段数据


    前面写了用GDAL读取数据集和波段信息,使用GDAL最重要的就是读取图像的波段数据,因为对图像的处理就是对数据(也可以说是像素点)的处理。这里讨论下gdal读取波段数据。

    参考文章:http://www.gdal.org/gdal_tutorial.html

    这里有个中文翻译版,翻译的还是可以的:http://opencv-extension-library.googlecode.com/svn/doc/gdal-doc/gdal_tutorial.html

    读取波段数据

    gdal读取波段数据的接口为RasterIO,这是一个及其重要的函数,GDALDataset和GDALRasterBand类都有这个函数,利用GDALDataset类中的RasterIO时可以按指定波段数并按一定的波段序读取数据,GDALRasterBand类中的RasterIO可以读取该波段的数据,读数据时可以全部读取、读取某一块或抽样读取。用的多的是GDALRasterBand类的RaterIO函数,下面就说下这个函数,函数原型如下:

    CPLErr GDALRasterBand::RasterIO    (    
    GDALRWFlag eRWFlag, //读写标志。GF_Read:读取数据到缓存 GF_Write:将缓存中数据写入数据集的波段
    int nXOff, //起始X方向像素位置
    int nYOff, //起始Y方向像素位置
    int nXSize, //数据的X方向像素大小
    int nYSize, //数据的Y方向像素大小 注:以上四个参数制定了要读取数据的位置和大小
    void * pData, //缓存
    int nBufXSize, //缓存的X方向像素大小
    int nBufYSize, //缓存的Y方向像素大小
    GDALDataType eBufType, //数据类型,指定缓存中的数据类型
    int nPixelSpace, //读取每个像素的字节偏移量,即下一个读取的的像素与此时读取的像素的字节距离,默认为0
    int  nLineSpace     //读取每一行像素的字节偏移量,默认为0
    )    

    参数意义见注释,

    nPixelSpace为0时,表示偏移的字节量为eBufType大小的字节数

    nLineSpace为0时,表示偏移的字节量为eBufType * nBufXSize字节数

    采样实现:设置最后两个参数,设置nPixelSpace指定每行隔几个像素点进行读取,设置nLineSpace指定每隔几行读取,注意缓存的大小。

    对数据全部读取示例:

    //数据集注册及对象获取这里不赘述,见上篇
    int sizeX = poDataset->GetRasterXSize();

    int sizeY = poDataset->GetRasterYSize();
    unsigned char *pMemData1;
    pMemData = (unsigned char*)CPLMalloc(sizeX * sizeY);
    poBand = poDataset->GetRasterBand(1);
    poBand->RasterIO(GF_Read,
    0,0,
    sizeX,sizeY,
    pMemData,
    sizeX,sizeY,
    GDT_Byte,
    0,0);
    CPLFree(pMemData);

    有时,需要每行进行字节对齐,即每行的字节数为8的倍数,即位数为32的倍数(32位系统一个内存单元是32位),对于上面的情况,如下:

    bytePerLine=(sizeX*8=31)/32*4     即pMemData每行的位数就是32的倍数了(为什么这样计算,自个体会吧)

    每行的字节对齐后,pMemData每行就不是sizeX了,应该是bytePerLine,对应上面的代码也要改变。

    分块读取:

    这里,如果图像很大,一般遥感图像,特别是高分辨率图像数据量都很大,直接全部读取对于内存开销会很大,这时可以采取分块读取的方法,比如每100为一个数据块进行读取,这样可以减小内现存开销。分块的例子(以每100行为一块为例):

    int sizeX = poDataset->GetRasterXSize();
    int sizeY = poDataset->GetRasterYSize();
    unsigned char *pMemData1;
    //100行一块
    pMemData = (unsigned char*)CPLMalloc(sizeX * 100);

    poBand = poDataset->GetRasterBand(1);
    for(int i=0;i<sizeY/100;i++)
    {
    poBand->RasterIO(GF_Read,
    0,i*100,
    sizeX,100,
    pMemData,
    sizeX,100,
    GDT_Byte,
    0,0);
    }
    CPLFree(pMemData);

    注意:上面的代码中还有最后剩下的不到100行的数据没有读,这里只为了说明怎么分块,剩下的数据就不管了。实际中千万要加上。

    读取完后申请的内存要记得释放掉。
    GDALRasterBand类的RasterIO函数可以满足大部分要求,也比较容易理解,波段多时大不了多用几次。GDALDataset类的RasterIO目前没怎么用,只是多了几个参数,功能更强大,需要时再去用吧。



  • 相关阅读:
    log4j配置文件动态指定日志文件名称
    如何在natTable表格上添加双击事件
    如何让natTable表格支持自定义多个右键菜单
    java1.7集合源码阅读:ArrayList
    关于java1.7集合源码阅读
    多线程之:如何避免死锁
    idea控制台中文乱码“淇℃伅”
    独立的js文件中不能使用EL表达式取值
    不能在jsp页面<c:choose>对标签中使用<!---->进行注释
    Excel导入工具类
  • 原文地址:https://www.cnblogs.com/Romi/p/2424073.html
Copyright © 2020-2023  润新知