利用Python把遥感影像的某几个波段合成

刚刚开始想着手学习Python,决定从最基础的读写遥感影像开始。学习借鉴了网上很多前辈们的经验,自己出现了一些小问题写在这里,算是记录一下。

这是USGS上下载的一景Landsat8影像,地点在青海。

利用Python把遥感影像的某几个波段合成_第1张图片利用Python把遥感影像的某几个波段合成_第2张图片

用ENVI截取了扎陵湖的一部分,真彩色合成图如下:

利用Python把遥感影像的某几个波段合成_第3张图片

想利用Python把nir,red,green三个波段合成假彩色,代码如下:

import os

import numpy as np
from osgeo import gdal

class IMAGE:

    # 读图像文件
    def read_img(self,filename):

        dataset = gdal.Open(filename)  # 打开文件

        im_width = dataset.RasterXSize  # 栅格矩阵的列数
        im_height = dataset.RasterYSize  # 栅格矩阵的行数
        # im_bands = dataset.RasterCount  # 波段数
        im_geotrans = dataset.GetGeoTransform()  # 仿射矩阵,左上角像素的大地坐标和像素分辨率
        im_proj = dataset.GetProjection()  # 地图投影信息,字符串表示
        im_data = dataset.ReadAsArray(0, 0, im_width, im_height)

        del dataset   #关闭对象dataset,释放内存
        # return im_width, im_height, im_proj, im_geotrans, im_data,im_bands
        return  im_proj, im_geotrans, im_data, im_width,im_height,im_bands

    # 遥感影像的存储
    # 写GeoTiff文件
    def write_img(self,filename, im_proj, im_geotrans, im_data):
        # 判断栅格数据的数据类型
        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_bands, im_height, im_width = im_data.shape
        else:
            im_bands, (im_height, im_width) = 1, im_data.shape   #没看懂

        # 创建文件时 driver = gdal.GetDriverByName("GTiff"),数据类型必须要指定,因为要计算需要多大内存空间。
        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

if __name__ == "__main__":
    os.chdir(r'F:\ProfessionalProfile\DataRelevant\testZone')   #切换路径到待处理图像所在文件夹
    run=IMAGE()
    # 第一步
    # proj, geotrans, data1, row1, column1,band = run.read_img(r'F:\ProfessionalProfile\DataRelevant\testZone\testZone1_Bnad5.tif')  # 读数据
    # proj, geotrans, data2, row2, column2,band = run.read_img(r'F:\ProfessionalProfile\DataRelevant\testZone\testZone1_Bnad4.tif')  # 读数据
    # proj, geotrans, data3, row3, column3,band = run.read_img(r'F:\ProfessionalProfile\DataRelevant\testZone\testZone1_Bnad3.tif')  # 读数据
    proj, geotrans, data1, row1, column1, band  = run.read_img('testZone1_Bnad5.tif')  # 读数据
    proj, geotrans, data2, row2, column2, band = run.read_img('testZone1_Bnad4.tif')  # 读数据
    proj, geotrans, data3, row3, column3, band = run.read_img('testZone1_Bnad3.tif')  # 读数据
    # 第二步:将上述读取的3个波段放到一个数组中
    # 出错( 'str' object has no attribute 'datatype')
    data = np.array((data1,data2,data3), dtype=data1.dtype)  # 按序将3个波段像元值放入
    # 第三步
    run.write_img('jcs543.tif', proj, geotrans, data)  # 写为3波段数据,假彩色,nir,red,green

运行完以后,把结果在ENVI中打开,如下:

利用Python把遥感影像的某几个波段合成_第4张图片

 

出现了以下两个错误:

1.ValueError: too many values to unpack (expected 5)。报错显示在72行。找了一下,发现定义的read_img函数返回6个参数,而后续调用只用到了5个参数。去掉read_img函数中返回的im_bands返回值,或者在后续调用read_img函数的时候加上一个band参数就可以了。

利用Python把遥感影像的某几个波段合成_第5张图片

利用Python把遥感影像的某几个波段合成_第6张图片

2.解决上述问题之后,又报错AttributeError: 'str' object has no attribute 'dtype'。发现在调用read_img函数的时候,参数顺序和返回值顺序不一致。调整顺序以后再运行就没有问题了。

这也侧面告诉了自己:光拼凑、借鉴别人写的不行,还是有很多小问题需要注意的。

利用Python把遥感影像的某几个波段合成_第7张图片

 

 

 

你可能感兴趣的:(Python地理数据处理,python)