天天看点

【Python+GIS】图像转置、定义栅格投影1. 实验背景与数据2. 实验说明3.代码4. 总结与反思

图像转置、定义栅格投影

  • 1. 实验背景与数据
  • 2. 实验说明
    • 2.1 实验目的
    • 2.2 参考文献
  • 3.代码
    • 3.1 转置
    • 3.2 定义投影
  • 4. 总结与反思

1. 实验背景与数据

最近下载了程洁老师的LST数据,这个数据集填充了MOD11 LST的空缺,遂使用此数据集进行后面的操作。

数据可以在国家青藏高原数据中心开放获取,贴一张数据简介:

【Python+GIS】图像转置、定义栅格投影1. 实验背景与数据2. 实验说明3.代码4. 总结与反思

此数据集为hdf格式,包含有4个波段图层,纬度、经度、LST和LST的质量,但是这样分开就有一个小问题,把LST拖进ArcGIS里面,会显示没有投影,而且并不是正的,如下图所示:

【Python+GIS】图像转置、定义栅格投影1. 实验背景与数据2. 实验说明3.代码4. 总结与反思
【Python+GIS】图像转置、定义栅格投影1. 实验背景与数据2. 实验说明3.代码4. 总结与反思

也就是说,咱们想要使用这个数据,得进行一些小处理。

2. 实验说明

2.1 实验目的

(1)转置。将竖着的图像转为横着。

(2)定义投影。加入经纬度地理坐标。

2.2 参考文献

《GDAL(python) 之GeoTransform》

《【GIS】GIS中仿射变换的六参数》

《python+GDAL给图像设置地理参考(GeoTransform和Projection的设置)》

3.代码

3.1 转置

from osgeo import gdal, gdalconst
import numpy as np
import sys
import copy
import os

outputFolder=r"C:\Users\10366\Desktop\test\test\transfer\2"
inputFloder1=r"C:\Users\10366\Desktop\test\test\output"

input_folder_list_LN=os.listdir(inputFloder1) #读取文件夹里所有文件
LN_list=[] #创建一个只装tif格式的列表
for filename in input_folder_list_LN:  #遍历 
    filelast=filename[-3:]
    if  filelast=="tif":
        LN_list.append(filename) 

referencepath=r"C:\Users\10366\Desktop\test\LST REFERENCE.tif"

for i in range(0,len(LN_list)):
    img_path=inputFloder1+"\\"+LN_list[i]
    dataset = gdal.Open(img_path)  # 取出第j个波段
    img_width = dataset.RasterXSize
    img_height = dataset.RasterYSize
    img_data = np.array(dataset.ReadAsArray(0, 0, img_width, img_height), dtype=float)  # 将数据写成数组,对应栅格矩阵
    img_data=img_data.T  #转置!

# 保存为TIF格式
    save_path=outputFolder+"\\"+LN_list[i]
    driver = gdal.GetDriverByName("GTiff")
    datasetnew = driver.Create(save_path, img_height,img_width, 1, gdal.GDT_Float32)
    #datasetnew.SetGeoTransform(adf_GeoTransform)
    #datasetnew.SetProjection(im_Proj)
    band = datasetnew.GetRasterBand(1)
    band.WriteArray(img_data)
    datasetnew.FlushCache()  # Write to disk.必须有清除缓存
    
print("OK")
           

转置的重点是T,这在矩阵中是较为常见的:

3.2 定义投影

from osgeo import gdal, osr
from osgeo import gdalconst
import sys
import copy
import os
import numpy as np

inputFloder1=r"C:\Users\10366\Desktop\test\test\transfer\initial"
outputFolder=r"C:\Users\10366\Desktop\test\test\transfer\3"
reference=r"C:\Users\10366\Desktop\test\LST REFERENCE.tif" #参考影像


#LN文件夹
input_folder_list_LN=os.listdir(inputFloder1) #读取文件夹里所有文件
LN_list=[] #创建一个只装tif格式的列表
for filename in input_folder_list_LN:  #遍历 
    filelast=filename[-3:]
    if  filelast=="tif":
        LN_list.append(filename)  

for i in range(0,len(LN_list)):
    LN=gdal.Open(inputFloder1+"\\"+LN_list[i])
    ref=gdal.Open(reference)  

    #geotransform = LN.GetGeoTransform()
    projection=ref.GetProjection() #参考影像的投影坐标系
    cols = LN.RasterXSize
    rows = LN.RasterYSize
    
    LNBand = LN.GetRasterBand(1)
    LNData = LNBand.ReadAsArray(0,0,cols,rows)
    
    xmin=73.55  #经度最小值
    xmax=134.99 #经度最大值
    ymin=18.33 #纬度最小值
    ymax=53.47 #纬度最大值
    xscale=(xmax-xmin)/cols #经度方向的分辨率
    yscale=(ymax-ymin)/rows #纬度方向的分辨率
    GeoList=[xmin,xscale,0.0,ymax,0.0,-yscale] #设置地理坐标转换参数
    geotransform=tuple(GeoList) #创建地理坐标转换

    result = LNData 
    resultPath = outputFolder+"\\pro1.tif" #结果的保存路径名
    print(resultPath)

    format = "GTiff"   
    driver = gdal.GetDriverByName(format)
    ds = driver.Create(resultPath, cols, rows, 1, gdal.GDT_Float32)
    ds.SetGeoTransform(geotransform)
    ds.SetProjection(projection)
    band  = ds.GetRasterBand(1)
    band.WriteArray(result)
    ds.FlushCache()  
    ds = None

print("ok")
           

结果如下图所示:

【Python+GIS】图像转置、定义栅格投影1. 实验背景与数据2. 实验说明3.代码4. 总结与反思

4. 总结与反思

  1. 转置时,由于数组的shape变了,所以在创建影像的时候,要注意行数和列数的设置。
img_width = dataset.RasterXSize #原来的列数
img_height = dataset.RasterYSize #原来的行数
datasetnew = driver.Create(save_path, img_height,img_width, 1, gdal.GDT_Float32) 
           
  1. geotransform是元组,元组的数据是不能修改的,所以得先创建list,再list转元组tuple
GeoList=[xmin,xscale,0.0,ymax,0.0,-yscale] #设置地理坐标转换参数
geotransform=tuple(GeoList) #创建地理坐标转换
           
  1. 在设置地理坐标转换参数的时候,有六个参数,分别是:

    (左上角x坐标, 水平分辨率,旋转参数, 左上角y坐标,旋转参数,竖直分辨率)

    **要注意前面是先分辨率再旋转参数,后面是先旋转参数再分辨率,**我之前就是以为这俩是一样的,屡战屡败,图像根本出不来。

完成上述操作后,就处理好了,可以使用了。