Python遥感影像数据读写

主要参考:https://blog.csdn.net/theonegis/article/details/80089375

1 影像基本信息读取

from osgeo import gdal

# 打开栅格影像
ds = gdal.Open('data\\Pic_Test.tif')

# =============================================================================
# 影像信息提取
# =============================================================================

# 投影
proj = ds.GetProjection()
 # 返回的是六个参数的tuple
trans = ds.GetGeoTransform() 
#波段数
nbands = ds.RasterCount
#行列数
nx = ds.RasterXSize
ny = ds.RasterYSize

# 获取数据集的元数据信息
metadata = ds.GetMetadata_Dict()
for key, value in metadata.items():
    print(f'{key} -> {value}')

b_Type = []
b_TypeName = []
b_NoData = []
b_MINMAX = []

for b in range(nbands):
    # 注意GDAL中的band计数是从1开始的
    band = ds.GetRasterBand(b + 1)
    # 波段数据的一些信息
    b_Type.append(band.DataType)  # DataType属性返回的是数字
    b_TypeName.append(gdal.GetDataTypeName(b_Type[b]))  #数据类型
    b_NoData.append(band.GetNoDataValue())  # NoData值
    b_MINMAX.append( band.ComputeRasterMinMax())  # 最大最小值

2 Dataset转为Numpy的ndarray

# 1 在数据集层面转换
image = ds.ReadAsArray()

print(f'数据的尺寸:{image.shape}')
# 输出结果为:数据的尺寸:(3, 4800, 4800)
# 这说明ReadAsArray方法将每个波段都转换为了一个二维数组

# 获得第一个波段的数据
band1 = image[0]

# 2 在波段层面的转换


for b in range(nbands):
    # 注意GDAL中的band计数是从1开始的
    band = ds.GetRasterBand(b + 1)
    band = band.ReadAsArray()
    print(f'波段大小:{band.shape}')

3 格式转换

# =============================================================================
# 格式转换
# GTiff -raster- (rw+vs): GeoTIFF
# HFA -raster- (rw+v): Erdas Imagine Images (.img)
# ENVI -raster- (rw+v): ENVI .hdr Labelled
# =============================================================================
    
# 方法一:Translate()函数
ds_env1 = gdal.Translate('data\\Pic_Test-env', ds, format='ENVI')

#方法二:CreateCopy()方法
driver = gdal.GetDriverByName('ENVI')
ds_env2 = driver.CreateCopy('data\\Pic_Test-env2', ds)



# 关闭数据集
ds = None
ds_env1 = None
ds_env2 = None

4 文件读写

4.1函数

from osgeo import gdal

#读图像文件
def read_img(filename):
    dataset=gdal.Open(filename)       #打开文件

    im_width = dataset.RasterXSize    #栅格矩阵的列数
    im_height = dataset.RasterYSize   #栅格矩阵的行数

    im_geotrans = dataset.GetGeoTransform()  #仿射矩阵
    im_proj = dataset.GetProjection() #地图投影信息
    im_data = dataset.ReadAsArray() #将数据写成数组,对应栅格矩阵

    del dataset 
    return im_proj,im_geotrans,im_data,im_width,im_height

#写文件,以写成tif为例
# =============================================================================
# 其他格式
# GTiff -raster- (rw+vs): GeoTIFF
# HFA -raster- (rw+v): Erdas Imagine Images (.img)
# ENVI -raster- (rw+v): ENVI .hdr Labelled
# =============================================================================
def write_img(filename,im_proj,im_geotrans,im_data):
    #gdal数据类型包括
    #gdal.GDT_Byte, 
    #gdal .GDT_UInt16, gdal.GDT_Int16, gdal.GDT_UInt32, gdal.GDT_Int32,
    #gdal.GDT_Float32, gdal.GDT_Float64

    #判断栅格数据的数据类型
    if 'int8' in im_data.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in im_data.dtype.name:
        datatype = gdal.GDT_UInt16
    else:
        datatype = gdal.GDT_Float32

    #判读数组维数
    if len(im_data.shape) == 3:
        im_bands, im_height, im_width = im_data.shape
    else:
        im_bands, (im_height, im_width) = 1,im_data.shape 

    #创建文件
    driver = gdal.GetDriverByName("GTiff")            #数据类型必须有,因为要计算需要多大内存空间
    dataset = driver.Create(filename, im_width, im_height, im_bands, datatype)

    dataset.SetGeoTransform(im_geotrans)              #写入仿射变换参数
    dataset.SetProjection(im_proj)                    #写入投影

    if im_bands == 1:
        dataset.GetRasterBand(1).WriteArray(im_data)  #写入数组数据
    else:
        for i in range(im_bands):
            dataset.GetRasterBand(i+1).WriteArray(im_data[i])

    del dataset

4.2 读写影像

from osgeo import gdal
import numpy as np
import IMG_RW as ig

im_proj,im_geotrans,image,im_width,im_height = ig.read_img('data\\Pic_Test.tif')

#计算NDVI##############################################################
bnd_red = image[0].astype(float)  # 红波段
bnd_nir = image[3].astype(float)  # 近红外波段
idx_ndvi = (bnd_nir - bnd_red) / (bnd_nir + bnd_red)  # NDVI

#创建影像 法一:函数
out1_file = 'data\\NDVI.tif'
ig.write_img(out1_file,im_proj,im_geotrans,idx_ndvi)

#创建影像 法二:copy模板(out1_file)
out2_file = 'data\\NDVI-2.tif'
driver = gdal.GetDriverByName('GTiff')
dataset = driver.CreateCopy(out2_file, gdal.Open(out1_file))
dataset.GetRasterBand(1).WriteArray(idx_ndvi)  #写入数组数据


#波段组合#################################################################

image321 = np.array((image[2], image[1], image[0]),dtype = image.dtype)
#法一:
out3_file = 'data\\Pic_Test321.tif'
ig.write_img(out3_file,im_proj,im_geotrans,image321)

#法二:
out4_file = 'data\\Pic_Test321-2.tif'
driver = gdal.GetDriverByName('GTiff')
dataset2 = driver.CreateCopy(out4_file, gdal.Open(out3_file))
for i in range(3):
    dataset2.GetRasterBand(i+1).WriteArray(image321[i])
  • 8
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值