Python下GDAL安装与使用

Jun 14,2017   23815 words   86 min


之所以想在Python下使用GDAL,其实源自一个很实际的需求。虽然OpenCV处理图像能力很强, 但是有个短板就是无法加载真正的遥感影像进行处理。因为遥感影像原图一般都1G多, 利用OpenCV直接打开会提示内存不足。 于是自然地在网上找OpenCV打开大图像的相关内容,发现并没有这方面的资料可以参考。 但我们又有读取原始遥感影像的需求。所以必须要解决这个问题。 于是自然想到了两个办法,一是利用Python读取大文件的方法。但是看了相关内容后发现, 主要是针对文本文件的读取,并不适合影像。于是放弃。第二种方法是使用GDAL来读取遥感影像。 这种方法就是传统也是最有效的办法。但是和之前配置各种环境一样,安装过程也是一波三折,于是就有了这篇博客。 记录一下走过的坑。

一、Python下GDAL的安装

在Python下安装GDAL其实可以分两大部分,一部分是”Core”的安装,另一部分是”Binding”的安装。 可以理解为Core是GDAL的公有DLL库,所有语言都会调用这些DLL实现功能,而Binding则相当于是这些库的Python打包接口,以便Python可以调用。 虽然也可以使用pip安装”pip install gdal”,但是经过测试会有各种编译的错误,所以不推荐用这种方式安装。 在这篇博客中对不同环境下安装GDAL进行了简单的总结,建议先看看。

1.下载安装包

打开这个网站如下图,选择对应的安装包。 选择时有几个需要注意的地方。首先是Compiler,这个版本要和你电脑上的VS版本对应。 其次是Arch.,注意这里并不是与你系统的位数保持一致,而是要和Python位数保持一致。 例如在我的电脑上有VS2010,系统是64位但安装了32位的Python, 所以最终选择的版本是release-1600-gdal-2-1-3-mapserver-7-0-4。 点击便会进入下一个界面,有更多的内容可供选择,如下图。 首先根据我们安装的Python版本选择对应的安装包,如我的Python是2.7版本的,就选择对应的2.7。 Python是32位的就选择win32。这里我们选择如下安装包。 选择好后点击相应的安装包下载即可。 要注意底下的提示,告诉我们在安装好Core后,需要手动将路径添加到系统变量中,否则可能找不到。

2.安装

(1)首先安装gdal-201-1600-core。
欢迎界面如下: 等待安装: 安装完成: 安装完成之后,我们需要手动将安装目录添加到系统变量中,以便系统能够找到。 它默认会安装到C:\Program Files(x86)\GDAL\下,如果是64位的就是C:\Program Files\GDAL\。 我们只需要将这个路径添加进系统变量即可。 检测是否添加成功,可以打开系统的“运行”,然后输入”gdalinfo –version”,如果出现如下提示说明安装成功。

(2)安装GDAL for Python
安装界面如下图。 注意这里第二项选择”Entire feature…“,同时在下面的路径中填写本机的Python安装路径,这样程序会自动把文件放到Lib\site-packages\下面,很方便。 完成后打开Python的包目录,可以发现已经多了如下文件,这就是我们在Python下调用需要用到的文件了。

3.测试

最后我们可以打开PyCharm测试一下,可以看到导入包没有问题,程序正常退出。这样GDAL的Python环境就配置安装完了。

二、GDAL读取遥感影像

1.影像基本信息获取

利用GDAL读取遥感原始影像非常简单,代码如下:

from osgeo import gdal
from gdalconst import *

dataset = gdal.Open("E:\\GF_Image.tiff", GA_ReadOnly)
if dataset is None:
    print "None"
else:
    print 'Driver:\n', 'ShortName:', dataset.GetDriver().ShortName, 'LongName:', dataset.GetDriver().LongName
    print 'Size is:\n', dataset.RasterXSize, '*', dataset.RasterYSize, '*', dataset.RasterCount
    print 'Projection is ', dataset.GetProjection()

结果如下,在控制台中输出了文件的相关信息: 这样便完成了对遥感影像的最基本信息的读取。

2.影像数据读取

利用GDAL自然是不满足仅仅读取影像的那些“头文件”信息的,当然要读取影像数据进行处理或者显示出来。 在打开影像之前先对GDAL的相关函数、属性有个基本的了解。

dir(dataset)、help(dataset)

这两个函数是Python的函数,第一个用于列出某个对象所包含的所有可用函数、属性等等。 第二个则不仅列出函数、属性,还会对每个条目有简短的说明,参数等等。 对于GDAL的dataset类型,help()打印出的信息如下:

Help on Dataset in module osgeo.gdal object:

class Dataset(MajorObject)
 |  Proxy of C++ GDALDatasetShadow class
 |  
 |  Method resolution order:
 |      Dataset
 |      MajorObject
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  AddBand(self, *args, **kwargs)
 |      AddBand(self, GDALDataType datatype = GDT_Byte, char options = None) -> CPLErr
 |  
 |  BeginAsyncReader(self, xoff, yoff, xsize, ysize, buf_obj=None, buf_xsize=None, buf_ysize=None, buf_type=None, band_list=None, options=[])
 |  
 |  BuildOverviews(self, *args, **kwargs)
 |      BuildOverviews(self, char resampling = "NEAREST", int overviewlist = 0, 
 |          GDALProgressFunc callback = 0, void callback_data = None) -> int
 |  
 |  CommitTransaction(self, *args)
 |      CommitTransaction(self) -> OGRErr
 |  
 |  CopyLayer(self, *args, **kwargs)
 |      CopyLayer(self, Layer src_layer, char new_name, char options = None) -> Layer
 |  
 |  CreateLayer(self, *args, **kwargs)
 |      CreateLayer(self, char name, SpatialReference srs = None, OGRwkbGeometryType geom_type = wkbUnknown, 
 |          char options = None) -> Layer
 |  
 |  CreateMaskBand(self, *args)
 |      CreateMaskBand(self, int nFlags) -> CPLErr
 |  
 |  DeleteLayer(self, value)
 |      Deletes the layer given an index or layer name
 |  
 |  EndAsyncReader(self, *args)
 |      EndAsyncReader(self, AsyncReader ario)
 |  
 |  ExecuteSQL(self, *args, **kwargs)
 |      ExecuteSQL(self, char statement, Geometry spatialFilter = None, char dialect = "") -> Layer
 |  
 |  FlushCache(self, *args)
 |      FlushCache(self)
 |  
 |  GetDriver(self, *args)
 |      GetDriver(self) -> Driver
 |  
 |  GetFileList(self, *args)
 |      GetFileList(self) -> char
 |  
 |  GetGCPCount(self, *args)
 |      GetGCPCount(self) -> int
 |  
 |  GetGCPProjection(self, *args)
 |      GetGCPProjection(self) -> char
 |  
 |  GetGCPs(self, *args)
 |      GetGCPs(self)
 |  
 |  GetGeoTransform(self, *args, **kwargs)
 |      GetGeoTransform(self, int can_return_null = None)
 |  
 |  GetLayer(self, iLayer=0)
 |      Return the layer given an index or a name
 |  
 |  GetLayerByIndex(self, *args)
 |      GetLayerByIndex(self, int index = 0) -> Layer
 |  
 |  GetLayerByName(self, *args)
 |      GetLayerByName(self, char layer_name) -> Layer
 |  
 |  GetLayerCount(self, *args)
 |      GetLayerCount(self) -> int
 |  
 |  GetProjection(self, *args)
 |      GetProjection(self) -> char
 |  
 |  GetProjectionRef(self, *args)
 |      GetProjectionRef(self) -> char
 |  
 |  GetRasterBand(self, *args)
 |      GetRasterBand(self, int nBand) -> Band
 |  
 |  GetStyleTable(self, *args)
 |      GetStyleTable(self) -> StyleTable
 |  
 |  GetSubDatasets(self)
 |  
 |  GetTiledVirtualMem(self, *args, **kwargs)
 |      GetTiledVirtualMem(self, GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, 
 |          int nYSize, int nTileXSize, int nTileYSize, 
 |          GDALDataType eBufType, int band_list, GDALTileOrganization eTileOrganization, 
 |          size_t nCacheSize, 
 |          char options = None) -> VirtualMem
 |  
 |  GetTiledVirtualMemArray(self, eAccess=0, xoff=0, yoff=0, xsize=None, ysize=None, tilexsize=256, tileysize=256, datatype=None, band_list=None, tile_organization=2, cache_size=10485760, options=None)
 |      Return a NumPy array for the dataset, seen as a virtual memory mapping with
 |      a tile organization.
 |      If there are several bands and tile_organization = gdal.GTO_TIP, an element is
 |      accessed with array[tiley][tilex][y][x][band].
 |      If there are several bands and tile_organization = gdal.GTO_BIT, an element is
 |      accessed with array[tiley][tilex][band][y][x].
 |      If there are several bands and tile_organization = gdal.GTO_BSQ, an element is
 |      accessed with array[band][tiley][tilex][y][x].
 |      If there is only one band, an element is accessed with array[tiley][tilex][y][x].
 |      Any reference to the array must be dropped before the last reference to the
 |      related dataset is also dropped.
 |  
 |  GetVirtualMem(self, *args, **kwargs)
 |      GetVirtualMem(self, GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, 
 |          int nYSize, int nBufXSize, int nBufYSize, 
 |          GDALDataType eBufType, int band_list, int bIsBandSequential, 
 |          size_t nCacheSize, size_t nPageSizeHint, 
 |          char options = None) -> VirtualMem
 |  
 |  GetVirtualMemArray(self, eAccess=0, xoff=0, yoff=0, xsize=None, ysize=None, bufxsize=None, bufysize=None, datatype=None, band_list=None, band_sequential=True, cache_size=10485760, page_size_hint=0, options=None)
 |      Return a NumPy array for the dataset, seen as a virtual memory mapping.
 |      If there are several bands and band_sequential = True, an element is
 |      accessed with array[band][y][x].
 |      If there are several bands and band_sequential = False, an element is
 |      accessed with array[y][x][band].
 |      If there is only one band, an element is accessed with array[y][x].
 |      Any reference to the array must be dropped before the last reference to the
 |      related dataset is also dropped.
 |  
 |  ReadAsArray(self, xoff=0, yoff=0, xsize=None, ysize=None, buf_obj=None, buf_xsize=None, buf_ysize=None, buf_type=None, resample_alg=0, callback=None, callback_data=None)
 |      Reading a chunk of a GDAL band into a numpy array. The optional (buf_xsize,buf_ysize,buf_type)
 |      parameters should generally not be specified if buf_obj is specified. The array is returned
 |  
 |  ReadRaster(self, xoff=0, yoff=0, xsize=None, ysize=None, buf_xsize=None, buf_ysize=None, buf_type=None, band_list=None, buf_pixel_space=None, buf_line_space=None, buf_band_space=None, resample_alg=0, callback=None, callback_data=None)
 |  
 |  ReadRaster1(self, *args, **kwargs)
 |      ReadRaster1(self, int xoff, int yoff, int xsize, int ysize, int buf_xsize = None, 
 |          int buf_ysize = None, GDALDataType buf_type = None, 
 |          int band_list = 0, GIntBig buf_pixel_space = None, 
 |          GIntBig buf_line_space = None, 
 |          GIntBig buf_band_space = None, GDALRIOResampleAlg resample_alg = GRIORA_NearestNeighbour, 
 |          GDALProgressFunc callback = 0, 
 |          void callback_data = None) -> CPLErr
 |  
 |  ReleaseResultSet(self, *args)
 |      ReleaseResultSet(self, Layer layer)
 |  
 |  RollbackTransaction(self, *args)
 |      RollbackTransaction(self) -> OGRErr
 |  
 |  SetGCPs(self, *args)
 |      SetGCPs(self, int nGCPs, char pszGCPProjection) -> CPLErr
 |  
 |  SetGeoTransform(self, *args)
 |      SetGeoTransform(self, double argin) -> CPLErr
 |  
 |  SetProjection(self, *args)
 |      SetProjection(self, char prj) -> CPLErr
 |  
 |  SetStyleTable(self, *args)
 |      SetStyleTable(self, StyleTable table)
 |  
 |  StartTransaction(self, *args, **kwargs)
 |      StartTransaction(self, int force = True) -> OGRErr
 |  
 |  TestCapability(self, *args)
 |      TestCapability(self, char cap) -> bool
 |  
 |  WriteRaster(self, xoff, yoff, xsize, ysize, buf_string, buf_xsize=None, buf_ysize=None, buf_type=None, band_list=None, buf_pixel_space=None, buf_line_space=None, buf_band_space=None)
 |  
 |  __del__ lambda self
 |  
 |  __init__(self, *args, **kwargs)
 |  
 |  __repr__ = _swig_repr(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  RasterCount
 |      Dataset_RasterCount_get(Dataset self) -> int
 |  
 |  RasterXSize
 |      Dataset_RasterXSize_get(Dataset self) -> int
 |  
 |  RasterYSize
 |      Dataset_RasterYSize_get(Dataset self) -> int
 |  
 |  thisown
 |      The membership flag
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __swig_destroy__ = <built-in function delete_Dataset>
 |      delete_Dataset(Dataset self)
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from MajorObject:
 |  
 |  GetDescription(self, *args)
 |      GetDescription(self) -> char
 |  
 |  GetMetadata(self, domain='')
 |  
 |  GetMetadataDomainList(self, *args)
 |      GetMetadataDomainList(self) -> char
 |  
 |  GetMetadataItem(self, *args)
 |      GetMetadataItem(self, char pszName, char pszDomain = "") -> char
 |  
 |  GetMetadata_Dict(self, *args)
 |      GetMetadata_Dict(self, char pszDomain = "") -> char
 |  
 |  GetMetadata_List(self, *args)
 |      GetMetadata_List(self, char pszDomain = "") -> char
 |  
 |  SetDescription(self, *args)
 |      SetDescription(self, char pszNewDesc)
 |  
 |  SetMetadata(self, *args)
 |      SetMetadata(self, char papszMetadata, char pszDomain = "") -> CPLErr
 |      SetMetadata(self, char pszMetadataString, char pszDomain = "") -> CPLErr
 |  
 |  SetMetadataItem(self, *args)
 |      SetMetadataItem(self, char pszName, char pszValue, char pszDomain = "") -> CPLErr
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from MajorObject:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

可以看到有很多可以用的函数、属性等。下面的介绍主要从它们中选取。

dataset.GetDescription()

该函数用于获取dataset的描述信息,对于只有一张影像的数据集,返回的就是其文件路径,如”E:\GF_Image.tiff”。

dataset.RasterCount

dataset的属性,表示栅格数据集所包含的波段数,返回值为整数。如对于示例中的影像,包含4个波段,返回值为4。

dataset.GetRasterBand(BandNumber)

根据波段号获取该波段。注意波段号是从1开始的,而不是从0。

dataset.RasterXSize

dataset属性,数据集X方向上的像素个数,例如12000。

dataset.RasterYSize

dataset属性,数据集Y方向上的像素个数,例如13400。

dataset.ReadRaster()、dataset.ReadAsArray()

在上面打印出的帮助信息中也可以看到,它们有非常多的参数。 这两个函数的作用都是读取图像数据,不同的是一个以二进制返回数据,一个以数组形式返回数据。但传入的参数是类似的。 有下面如下共同的参数:

  • xoff、yoff、xsize、ysize:用于指定在原图中需要读取的部分。 该部分以(xoff,yoff)坐标开始,分别沿x、y轴读取xsize、ysize个像素。
  • buf_xsize、buf_ysize:可对读取出的这一部分图像进行缩放,这两个参数用于定义缩放后图像最终的宽高,GDAL会自动缩放到这个大小。
  • buf_type:如果要读取的图像数据类型不是你想要的(比如原图数据类型是short,你要把它们缩小成byte),就可以设置它为byte。
  • band_list:适应多波段情况。可以指定读取的波段序列。
dir(band)、help(band)

与dataset类似,这里输入help,可以得到有关波段的帮助信息。

Help on Band in module osgeo.gdal object:

class Band(MajorObject)
 |  Proxy of C++ GDALRasterBandShadow class
 |  
 |  Method resolution order:
 |      Band
 |      MajorObject
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  Checksum(self, *args, **kwargs)
 |      Checksum(self, int xoff = 0, int yoff = 0, int xsize = None, int ysize = None) -> int
 |  
 |  ComputeBandStats(self, *args)
 |      ComputeBandStats(self, int samplestep = 1)
 |  
 |  ComputeRasterMinMax(self, *args)
 |      ComputeRasterMinMax(self, int approx_ok = 0)
 |  
 |  ComputeStatistics(self, *args)
 |      ComputeStatistics(self, bool approx_ok, GDALProgressFunc callback = 0, void callback_data = None) -> CPLErr
 |  
 |  CreateMaskBand(self, *args)
 |      CreateMaskBand(self, int nFlags) -> CPLErr
 |  
 |  DeleteNoDataValue(self, *args)
 |      DeleteNoDataValue(self) -> CPLErr
 |  
 |  Fill(self, *args)
 |      Fill(self, double real_fill, double imag_fill = 0.0) -> CPLErr
 |  
 |  FlushCache(self, *args)
 |      FlushCache(self)
 |  
 |  GetBand(self, *args)
 |      GetBand(self) -> int
 |  
 |  GetBlockSize(self, *args)
 |      GetBlockSize(self)
 |  
 |  GetCategoryNames(self, *args)
 |      GetCategoryNames(self) -> char
 |  
 |  GetColorInterpretation(self, *args)
 |      GetColorInterpretation(self) -> GDALColorInterp
 |  
 |  GetColorTable(self, *args)
 |      GetColorTable(self) -> ColorTable
 |  
 |  GetDataset(self, *args)
 |      GetDataset(self) -> Dataset
 |  
 |  GetDefaultHistogram(self, *args, **kwargs)
 |      GetDefaultHistogram(self, double min_ret = None, double max_ret = None, int buckets_ret = None, 
 |          GUIntBig ppanHistogram = None, 
 |          int force = 1, GDALProgressFunc callback = 0, 
 |          void callback_data = None) -> CPLErr
 |  
 |  GetDefaultRAT(self, *args)
 |      GetDefaultRAT(self) -> RasterAttributeTable
 |  
 |  GetHistogram(self, *args, **kwargs)
 |      GetHistogram(self, double min = -0.5, double max = 255.5, int buckets = 256, 
 |          int include_out_of_range = 0, int approx_ok = 1, 
 |          GDALProgressFunc callback = 0, void callback_data = None) -> CPLErr
 |  
 |  GetMaskBand(self, *args)
 |      GetMaskBand(self) -> Band
 |  
 |  GetMaskFlags(self, *args)
 |      GetMaskFlags(self) -> int
 |  
 |  GetMaximum(self, *args)
 |      GetMaximum(self)
 |  
 |  GetMinimum(self, *args)
 |      GetMinimum(self)
 |  
 |  GetNoDataValue(self, *args)
 |      GetNoDataValue(self)
 |  
 |  GetOffset(self, *args)
 |      GetOffset(self)
 |  
 |  GetOverview(self, *args)
 |      GetOverview(self, int i) -> Band
 |  
 |  GetOverviewCount(self, *args)
 |      GetOverviewCount(self) -> int
 |  
 |  GetRasterCategoryNames(self, *args)
 |      GetRasterCategoryNames(self) -> char
 |  
 |  GetRasterColorInterpretation(self, *args)
 |      GetRasterColorInterpretation(self) -> GDALColorInterp
 |  
 |  GetRasterColorTable(self, *args)
 |      GetRasterColorTable(self) -> ColorTable
 |  
 |  GetScale(self, *args)
 |      GetScale(self)
 |  
 |  GetStatistics(self, *args)
 |      GetStatistics(self, int approx_ok, int force) -> CPLErr
 |  
 |  GetTiledVirtualMem(self, *args, **kwargs)
 |      GetTiledVirtualMem(self, GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, 
 |          int nYSize, int nTileXSize, int nTileYSize, 
 |          GDALDataType eBufType, size_t nCacheSize, char options = None) -> VirtualMem
 |  
 |  GetTiledVirtualMemArray(self, eAccess=0, xoff=0, yoff=0, xsize=None, ysize=None, tilexsize=256, tileysize=256, datatype=None, cache_size=10485760, options=None)
 |      Return a NumPy array for the band, seen as a virtual memory mapping with
 |      a tile organization.
 |      An element is accessed with array[tiley][tilex][y][x].
 |      Any reference to the array must be dropped before the last reference to the
 |      related dataset is also dropped.
 |  
 |  GetUnitType(self, *args)
 |      GetUnitType(self) -> char
 |  
 |  GetVirtualMem(self, *args, **kwargs)
 |      GetVirtualMem(self, GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, 
 |          int nYSize, int nBufXSize, int nBufYSize, 
 |          GDALDataType eBufType, size_t nCacheSize, size_t nPageSizeHint, 
 |          char options = None) -> VirtualMem
 |  
 |  GetVirtualMemArray(self, eAccess=0, xoff=0, yoff=0, xsize=None, ysize=None, bufxsize=None, bufysize=None, datatype=None, cache_size=10485760, page_size_hint=0, options=None)
 |      Return a NumPy array for the band, seen as a virtual memory mapping.
 |      An element is accessed with array[y][x].
 |      Any reference to the array must be dropped before the last reference to the
 |      related dataset is also dropped.
 |  
 |  GetVirtualMemAuto(self, *args, **kwargs)
 |      GetVirtualMemAuto(self, GDALRWFlag eRWFlag, char options = None) -> VirtualMem
 |  
 |  GetVirtualMemAutoArray(self, eAccess=0, options=None)
 |      Return a NumPy array for the band, seen as a virtual memory mapping.
 |      An element is accessed with array[y][x].
 |      Any reference to the array must be dropped before the last reference to the
 |      related dataset is also dropped.
 |  
 |  HasArbitraryOverviews(self, *args)
 |      HasArbitraryOverviews(self) -> bool
 |  
 |  ReadAsArray(self, xoff=0, yoff=0, win_xsize=None, win_ysize=None, buf_xsize=None, buf_ysize=None, buf_type=None, buf_obj=None, resample_alg=0, callback=None, callback_data=None)
 |      Reading a chunk of a GDAL band into a numpy array. The optional (buf_xsize,buf_ysize,buf_type)
 |      parameters should generally not be specified if buf_obj is specified. The array is returned
 |  
 |  ReadBlock(self, *args, **kwargs)
 |      ReadBlock(self, int xoff, int yoff) -> CPLErr
 |  
 |  ReadRaster(self, xoff=0, yoff=0, xsize=None, ysize=None, buf_xsize=None, buf_ysize=None, buf_type=None, buf_pixel_space=None, buf_line_space=None, resample_alg=0, callback=None, callback_data=None)
 |  
 |  ReadRaster1(self, *args, **kwargs)
 |      ReadRaster1(self, double xoff, double yoff, double xsize, double ysize, 
 |          int buf_xsize = None, int buf_ysize = None, 
 |          int buf_type = None, GIntBig buf_pixel_space = None, 
 |          GIntBig buf_line_space = None, GDALRIOResampleAlg resample_alg = GRIORA_NearestNeighbour, 
 |          GDALProgressFunc callback = 0, 
 |          void callback_data = None) -> CPLErr
 |  
 |  SetCategoryNames(self, *args)
 |      SetCategoryNames(self, char papszCategoryNames) -> CPLErr
 |  
 |  SetColorInterpretation(self, *args)
 |      SetColorInterpretation(self, GDALColorInterp val) -> CPLErr
 |  
 |  SetColorTable(self, *args)
 |      SetColorTable(self, ColorTable arg) -> int
 |  
 |  SetDefaultHistogram(self, *args)
 |      SetDefaultHistogram(self, double min, double max, int buckets_in) -> CPLErr
 |  
 |  SetDefaultRAT(self, *args)
 |      SetDefaultRAT(self, RasterAttributeTable table) -> int
 |  
 |  SetNoDataValue(self, *args)
 |      SetNoDataValue(self, double d) -> CPLErr
 |  
 |  SetOffset(self, *args)
 |      SetOffset(self, double val) -> CPLErr
 |  
 |  SetRasterCategoryNames(self, *args)
 |      SetRasterCategoryNames(self, char names) -> CPLErr
 |  
 |  SetRasterColorInterpretation(self, *args)
 |      SetRasterColorInterpretation(self, GDALColorInterp val) -> CPLErr
 |  
 |  SetRasterColorTable(self, *args)
 |      SetRasterColorTable(self, ColorTable arg) -> int
 |  
 |  SetScale(self, *args)
 |      SetScale(self, double val) -> CPLErr
 |  
 |  SetStatistics(self, *args)
 |      SetStatistics(self, double min, double max, double mean, double stddev) -> CPLErr
 |  
 |  SetUnitType(self, *args)
 |      SetUnitType(self, char val) -> CPLErr
 |  
 |  WriteArray(self, array, xoff=0, yoff=0, resample_alg=0, callback=None, callback_data=None)
 |  
 |  WriteRaster(self, *args, **kwargs)
 |      WriteRaster(self, int xoff, int yoff, int xsize, int ysize, GIntBig buf_len, 
 |          int buf_xsize = None, int buf_ysize = None, 
 |          int buf_type = None, GIntBig buf_pixel_space = None, 
 |          GIntBig buf_line_space = None) -> CPLErr
 |  
 |  __get_array_interface__(self)
 |  
 |  __init__(self, *args, **kwargs)
 |  
 |  __repr__ = _swig_repr(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  DataType
 |      Band_DataType_get(Band self) -> GDALDataType
 |  
 |  XSize
 |      Band_XSize_get(Band self) -> int
 |  
 |  YSize
 |      Band_YSize_get(Band self) -> int
 |  
 |  thisown
 |      The membership flag
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from MajorObject:
 |  
 |  GetDescription(self, *args)
 |      GetDescription(self) -> char
 |  
 |  GetMetadata(self, domain='')
 |  
 |  GetMetadataDomainList(self, *args)
 |      GetMetadataDomainList(self) -> char
 |  
 |  GetMetadataItem(self, *args)
 |      GetMetadataItem(self, char pszName, char pszDomain = "") -> char
 |  
 |  GetMetadata_Dict(self, *args)
 |      GetMetadata_Dict(self, char pszDomain = "") -> char
 |  
 |  GetMetadata_List(self, *args)
 |      GetMetadata_List(self, char pszDomain = "") -> char
 |  
 |  SetDescription(self, *args)
 |      SetDescription(self, char pszNewDesc)
 |  
 |  SetMetadata(self, *args)
 |      SetMetadata(self, char papszMetadata, char pszDomain = "") -> CPLErr
 |      SetMetadata(self, char pszMetadataString, char pszDomain = "") -> CPLErr
 |  
 |  SetMetadataItem(self, *args)
 |      SetMetadataItem(self, char pszName, char pszValue, char pszDomain = "") -> CPLErr
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from MajorObject:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

band.XSize

band属性值,返回某一波段X方向的像素数。

band.YSize

band属性值,返回某一波段Y方向的像素数。

band.DataType

band属性值,表示band的数据类型,返回值是一个int类型的数。对应GDALConst中定义的类型。 输入help(gdalconst),可查看有关信息:

Help on module gdalconst:

NAME
    gdalconst - # import osgeo.gdalconst as a convenience

FILE
    d:\python2.7.13\lib\site-packages\gdalconst.py

DATA
    CE_Debug = 1
    CE_Failure = 3
    CE_Fatal = 4
    CE_None = 0
    CE_Warning = 2
    CPLES_BackslashQuotable = 0
    CPLES_CSV = 4
    CPLES_SQL = 3
    CPLES_URL = 2
    CPLES_XML = 1
    CPLE_AppDefined = 1
    CPLE_AssertionFailed = 7
    CPLE_FileIO = 3
    CPLE_IllegalArg = 5
    CPLE_NoWriteAccess = 8
    CPLE_None = 0
    CPLE_NotSupported = 6
    CPLE_OpenFailed = 4
    CPLE_OutOfMemory = 2
    CPLE_UserInterrupt = 9
    CXT_Attribute = 2
    CXT_Comment = 3
    CXT_Element = 0
    CXT_Literal = 4
    CXT_Text = 1
    DCAP_CREATE = 'DCAP_CREATE'
    DCAP_CREATECOPY = 'DCAP_CREATECOPY'
    DCAP_DEFAULT_FIELDS = 'DCAP_DEFAULT_FIELDS'
    DCAP_NOTNULL_FIELDS = 'DCAP_NOTNULL_FIELDS'
    DCAP_NOTNULL_GEOMFIELDS = 'DCAP_NOTNULL_GEOMFIELDS'
    DCAP_OPEN = 'DCAP_OPEN'
    DCAP_RASTER = 'DCAP_RASTER'
    DCAP_VECTOR = 'DCAP_VECTOR'
    DCAP_VIRTUALIO = 'DCAP_VIRTUALIO'
    DMD_CONNECTION_PREFIX = 'DMD_CONNECTION_PREFIX'
    DMD_CREATIONDATATYPES = 'DMD_CREATIONDATATYPES'
    DMD_CREATIONFIELDDATATYPES = 'DMD_CREATIONFIELDDATATYPES'
    DMD_CREATIONOPTIONLIST = 'DMD_CREATIONOPTIONLIST'
    DMD_EXTENSION = 'DMD_EXTENSION'
    DMD_EXTENSIONS = 'DMD_EXTENSIONS'
    DMD_HELPTOPIC = 'DMD_HELPTOPIC'
    DMD_LONGNAME = 'DMD_LONGNAME'
    DMD_MIMETYPE = 'DMD_MIMETYPE'
    DMD_SUBDATASETS = 'DMD_SUBDATASETS'
    GARIO_COMPLETE = 3
    GARIO_ERROR = 2
    GARIO_PENDING = 0
    GARIO_UPDATE = 1
    GA_ReadOnly = 0
    GA_Update = 1
    GCI_AlphaBand = 6
    GCI_BlackBand = 13
    GCI_BlueBand = 5
    GCI_CyanBand = 10
    GCI_GrayIndex = 1
    GCI_GreenBand = 4
    GCI_HueBand = 7
    GCI_LightnessBand = 9
    GCI_MagentaBand = 11
    GCI_PaletteIndex = 2
    GCI_RedBand = 3
    GCI_SaturationBand = 8
    GCI_Undefined = 0
    GCI_YCbCr_CbBand = 15
    GCI_YCbCr_CrBand = 16
    GCI_YCbCr_YBand = 14
    GCI_YellowBand = 12
    GDT_Byte = 1
    GDT_CFloat32 = 10
    GDT_CFloat64 = 11
    GDT_CInt16 = 8
    GDT_CInt32 = 9
    GDT_Float32 = 6
    GDT_Float64 = 7
    GDT_Int16 = 3
    GDT_Int32 = 5
    GDT_TypeCount = 12
    GDT_UInt16 = 2
    GDT_UInt32 = 4
    GDT_Unknown = 0
    GFT_Integer = 0
    GFT_Real = 1
    GFT_String = 2
    GFU_Alpha = 9
    GFU_AlphaMax = 17
    GFU_AlphaMin = 13
    GFU_Blue = 8
    GFU_BlueMax = 16
    GFU_BlueMin = 12
    GFU_Generic = 0
    GFU_Green = 7
    GFU_GreenMax = 15
    GFU_GreenMin = 11
    GFU_Max = 4
    GFU_MaxCount = 18
    GFU_Min = 3
    GFU_MinMax = 5
    GFU_Name = 2
    GFU_PixelCount = 1
    GFU_Red = 6
    GFU_RedMax = 14
    GFU_RedMin = 10
    GF_Read = 0
    GF_Write = 1
    GMF_ALL_VALID = 1
    GMF_ALPHA = 4
    GMF_NODATA = 8
    GMF_PER_DATASET = 2
    GPI_CMYK = 2
    GPI_Gray = 0
    GPI_HLS = 3
    GPI_RGB = 1
    GRA_Average = 5
    GRA_Bilinear = 1
    GRA_Cubic = 2
    GRA_CubicSpline = 3
    GRA_Lanczos = 4
    GRA_Mode = 6
    GRA_NearestNeighbour = 0
    GRIORA_Average = 5
    GRIORA_Bilinear = 1
    GRIORA_Cubic = 2
    GRIORA_CubicSpline = 3
    GRIORA_Gauss = 7
    GRIORA_Lanczos = 4
    GRIORA_Mode = 6
    GRIORA_NearestNeighbour = 0
    GTO_BIT = 1
    GTO_BSQ = 2
    GTO_TIP = 0
    OF_ALL = 0
    OF_GNM = 8
    OF_RASTER = 2
    OF_READONLY = 0
    OF_SHARED = 32
    OF_UPDATE = 1
    OF_VECTOR = 4
    OF_VERBOSE_ERROR = 64

在“GDT_”开头的项目中,可以查到2对应的是GDT_UInt16

band.GetNoDataValue()

获得的是无意义值,所谓无意义值可以理解为灰度范围的边界值。 0或者255在任何情况下都无意义。在很多情况下0、255需要和其他值一样表示一个实际意义。 虽然可能它最终会被显示得和黑色一样。 而一些位置上的点要表示的意思是“什么也不是”,它在那个位置上只是为了占一个位置,使得整体图像看起来像个矩形而已。 在做实际应用的时候两种值的处理将会完全不一样。所以需要设置无意义值,来和其他的值区别开来。

band.GetMaximum()

很容易理解,获取的是该波段中的最大值。需要注意的是这个最大值是除了无意义值(边界值)的。 例如我们在上面的图像中获得的数据类型是UInt16,能达到的最大值是65535。但其实利用这个函数获取到的最大值是1023。 所以要注意区别。

band.GetMinimum()

同理获取到的是这一波段中有效像素的最小值。例如在这里获取到的是175,而不是0。

band.ComputeRasterMinMax()

需要注意到是,如果直接利用上述两个函数会发现返回的结果是None,是空的。 因此实际想要获得真实的最大最小值需要使用这个函数。这样会返回一个元组,分别表示最大最小值。 例如在这里获取到的是(175.0, 1023.0)。

影像读取实例

下面代码展示了读取一幅遥感印象其中一个波段某一区域的影像,并显示出来。

# coding=utf-8
from osgeo import gdal
from gdalconst import *
from matplotlib import pyplot as plt

# 以只读方式打开遥感影像
dataset = gdal.Open("E:\\GF_Image.tiff", GA_ReadOnly)

# 输出影像信息
print 'Raster Info:'
print 'Driver:', dataset.GetDriver().ShortName
print 'Description:', dataset.GetDescription()
print 'BandCount:', dataset.RasterCount
print '\n'

# 获取影像的第一个波段
band_b = dataset.GetRasterBand(1)

# 输出波段信息
print 'Band Info:'
print 'XSize:', band_b.XSize
print 'YSize:', band_b.YSize
print 'DataType:', band_b.DataType
print 'Min&Max:', band_b.ComputeRasterMinMax()

# 读取第一个波段中从(4000,7300)开始,x、y方向各400像素的范围
data = band_b.ReadAsArray(4000, 7300, 400, 400)

# 调用Matplotlib以灰度形式显示图像
plt.imshow(data, cmap='gray')
plt.show()

结果如下:
控制台打印信息: 显示的图像信息:

三、实例练习

基于上面的知识,这里进行一个简单的练习,即利用GDAL为遥感影像制作小尺寸的缩略图。

# coding=utf-8
from osgeo import gdal
from gdalconst import *
from matplotlib import pyplot as plt

# 用户输入影像路径
image_path = raw_input("Input image path:\n")

# 以只读方式打开遥感影像
dataset = gdal.Open(image_path, GA_ReadOnly)

# 获取影像波段数
bandNumber = dataset.RasterCount

# 用户输入生成缩略图的波段
selected_band = input(
    bandNumber.__str__() + " band(s) in total.Input the number of band(1-" + bandNumber.__str__() + "):\n")

# 获取波段内容
band = dataset.GetRasterBand(selected_band)

# 设置缩放比例因子
scale = 0.1
scale = input("Input scale factor(0-1):\n")

# 原始影像大小
oriX = band.XSize
oriY = band.YSize

# 缩放后影像大小
newX = int(scale * oriX)
newY = int(scale * oriY)

# 输出信息
print 'Output Info:'
print "Original Size is ", oriX, " * ", oriY
print "New Size is ", newX, " * ", newY
print "Selected band is ", selected_band

# 用户交互,是否确定
result = raw_input("Are you sure?(Y/N)")

# 如果确定就继续,否则退出
if result.__eq__('Y') or result.__eq__('y'):
    print "Processing..."
    # 读取影像,这里最后两个参数即使在前面说过的最终需要的大小
    data = band.ReadAsArray(0, 0, band.XSize, band.YSize, newX, newY)
    print "OK."

    # 调用Matplotlib以灰度形式显示图像
    plt.imshow(data, cmap='gray')
    plt.show()
else:
    print "Exit."

根据提示输入相关参数,如下: 利用Matplotlib显示的缩略图如下: 这样便顺利完成了我们的目标。但是有个小小的问题没有解决,那就是在代码运行完成后, 程序总是会挂掉,如下图。而且还会提示”Process finished with exit code -1073741819 (0xC0000005)”。 搜索了错误代码也没找到满意的解决方案。 初步估计问题出在读取数据,与内存有关。但是数据都是正确读取出来了,也不影响使用。只是在关闭的时候会报错。 暂时不管它了。等以后继续研究找到原因了再说。 [2017-7-5]找到原因了,是Python版本问题。由于是32位Python,所以内存调用受限。换成64位就没问题了。 在这篇博客里给出了解决方案。

最后试了一下利用PyInstaller将代码转成了exe,如下图所示。 不得不佩服它的强大,在我包含了这些很大的包:GDAL、Matplotlib、os后, 还可以完美打包,在其它电脑上运行。依旧是机房“什么都没有”的Win7,截图如下: Matplotlib可以正常显示、保存。 通过PyInstaller将代码的可移植性大大提高了。只要打包完成,带着打包的文件,到哪里都可以运行。 即使那台电脑没有Python、没有GDAL,一样可以使用!这让我当到了之前用VS调C++写的代码, 总是缺各种库、各种依赖。就算调好了,也可能因为版本不兼容而出现各种问题。 而现在用Python写代码,最后用PyInstaller打包,所有这些问题都没有了。 不得不为PyInstaller点个赞,太棒了!
最后,还是附上exe下载地址,密码:6xai。

本文作者原创,未经许可不得转载,谢谢配合

返回顶部