学习GDAL

出入摄影测量与三维重建的大门,不免要接触对图像数据的处理。虽然现如今OpenCV3以其强大的算法和广泛的支持率傲视群雄,但谈到对图像的支持我们不得不提一提GDAL,这个老牌的图像处理的开源库。这篇学习笔记主要跟着这篇博文走(head first GDAL)可能需要科学上网,边看边学习吧。

环境配置

我之前已经写了用Clion配置GDAL的相关内容,因为暂时没有考虑到进行GDAL源码的调试和修改,我没有进行编译,只是下载的二进制库文件。这里也需要补充补充库的相关知识静态库和动态库。

影像

GDAL中也叫做数据集,可以分为多波段影像个多数据集影像。数据集(Dataset)包含了元数据投影信息和波段等等信息。其中使用了WTK来表示投影:


学习GDAL_第1张图片

通过GetProjectionRef()获取数据集投影信息

对于数据集内部。有两种方式可以表示栅格数据中像元的位置(图像中的某个点在影像中的序列号)和投影坐标系(不是经纬度,是投影到二维平面的地图坐标,二者可以通过地图投影进行相互转换)间的关系:一是放射变换,二是gcp点;放射变化由6参数实现, 可以通过GDALDataset::GetGeoTransform()获得放射变换参数数组。像元位置转换为投影坐标的公式为:

学习GDAL_第2张图片

六参数数组进行放射变换

波段

波段是真正存储数据的结构,GDAL中用GDALRasterBand类来表示单个波段。波段具有一些特殊的性质。

栅格数据的读写

项目可能暂时用不到矢量格式的读写,但是不涉及OGR的内容,但需要对栅格数据的读写做进一步的学习:
GDAL为每种格式提供了一个驱动GDALDriver,他对每种对应的格式进行管理(读取创建删除重命名复制从已有数据创建数据集等)。因此需要在所有程序开头添加GDALAllRegister()函数以注册所有GDAL支持的数据驱动。

数据读取

数据读取步骤如下:打开数据集—>打开数据集下所需的波段—>读取数据。

打开数据集

使用 GDALOpen()GDALOpenShared()函数(同一线程中多个GDALOpenShared打开的是同一个dataset的引用,而在不同线程中返回的是不同的对象)。

#include "gdal_priv.h"
#include "cpl_conv.h"

//...中间的程序

//所有程序前先加上
GDALAllRegister();
//pszFilename代表文件名,GA_ReadOnly表示以只读方式打开
//也可以使用GA_Update
//GDALOpenShared和GDALOpen可以互换
GDALDataset  *poDataset= (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );
if( poDataset == NULL )
{
    ...;//打开失败处理
}

打开波段

需要注意GDAL波段起始索引为1(非0!)使用GDALDataset->GetRasterBand(int BandIndex)获取波段.

#include "gdal_priv.h"
#include "cpl_conv.h"
//...中间的程序

//所有程序前先加上
GDALAllRegister();
GDALDataset  *poDataset= (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );//打开文件
if( poDataset == NULL )
{
    //...//打开失败处理
}
//打开数据集同上
//获取影像相关信息
int i,j,width,height,bandNum;
width = inDS->GetRasterXSize();//影像宽度
height = inDS->GetRasterYSize();//影像高度
bandNum = inDS->GetRasterCount();//影像波段数量

//将第一波段读入
double *data = new double[width*height];
GDALRasterBand *band = ds1->GetRasterBand(1);//获取第一波段,波段从1开始
//如果是在循环内,需要注意,波段从1开始;
//for(i=0;i < bandNum;i++){
// GDALRasterBand *band = ds1->GetRasterBand(i+1);//这里注意下
// ......对波段处理
//}

读取内容

使用RasterIO函数获取波段中的具体内容,示例代码:

///CPLErr GDALRasterBand::RasterIO (
///@param eRWFlag,     //读取或者写入,GF_Read或GF_Write
///@param nXOff,       //起始点x坐标
///@param nYOff,       //起始点y坐标
///@param nXSize,      //所需读取(写入)块宽度
///@param nYSize,      //所读(写)块高度
///@param * pData,     //所读(写)数据,指针,
///@param nBufXSize,   //一般跟nXSize一致,用于缩放图像,
///                      图像将按nBufXSize/nXsize在x尺度缩放(会自动重采样)
///                     ,一般不需要调整
///@param nBufYSize,   //一般跟nYSize一致
///@param eBufType,    //与pData的实际类型一致,GDT_Float64
///                      代表double,其他的可以跳到定义查看
///@param nPixelSpace,
///                      设置为0为自动判断,一般设为0
///                      表示的是当前像素值和下一个像素值之间的间隔,单位是字节
///                      例:byte类型,就是1,double类型,就是8
///@param nLineSpace
///                      设置为0为自动判断,一般设为0
///                      表示的是当前行和下一行的间隔,,单位是字节
///                      例如,一行300像素,类型为int,此时就是300*4 = 1200
///@return             //是否成功,成功返回CE_None ,失败返回 CE_Failure
CPLErr GDALRasterBand::RasterIO (
    GDALRWFlag eRWFlag,
    int     nXOff,
    int     nYOff,
    int     nXSize,
    int     nYSize,
    void * pData,
    int     nBufXSize,
    int     nBufYSize,
    GDALDataType    eBufType,
    int     nPixelSpace,
    int     nLineSpace
)

你可能感兴趣的:(学习GDAL)