【Python&RS】基于Python栅格数据/遥感影像投影转换

        有ENVI出现的地方,就一定会有Python的身影,为了解放双手方便批量投影转换,最近同步研究了一下如何利用Python实现遥感影像的投影转换,主打的就是一个懒。

        之前还分享过矢量数据的投影转换,这样矢量+栅格的全家桶不就有了嘛。感兴趣的可以自己查看:【Python&GIS】矢量数据投影转换(WGS84转地方坐标系)

一、查看影像信息

        为了水文章,这个其实不太重要,但有肯定更好,因为有些数据在ENVI中能看到地理坐标系,但GDAL却识别不到坐标系,这就会导致投影转换的失败。所以最好还是提前看一看,GDAL能不能读出投影信息吧。

        这里需要注意ds_geo和ds_prj两个输出,仿射地理变换参数和投影坐标系一样重要!

def Get_data(filepath):
    ds = gdal.Open(filepath)  # 打开数据集dataset
    ds_width = ds.RasterXSize  # 获取数据宽度
    ds_height = ds.RasterYSize  # 获取数据高度
    ds_bands = ds.RasterCount  # 获取波段数
    ds_geo = ds.GetGeoTransform()  # 获取仿射地理变换参数
    ds_prj = ds.GetProjection()  # 获取投影信息
    print("影像的宽度为:" + str(ds_width))
    print("影像的高度为:" + str(ds_height))
    print("仿射地理变换参数为:" + str(ds_geo))
    print("投影坐标系为:" + str(ds_prj))
    return ds_geo
    # data = ds.ReadAsArray(0, 0, ds_width, ds_height)  # 以数组的形式读取整个数据集

二、转换函数

        这里用到了GDAL中的Warp函数,是不是有点熟悉。之前裁剪也是用的这个函数,不得不说这个函数是真的强大,之前有文章介绍了其中的函数,大家有兴趣可以去看下,同时给个赞吧!【Python&RS】GDAL批量裁剪遥感影像/栅格数据

        Warp函数中的dstSRS参数就是目标的投影,这里采用EPSG编码,32651表示UTM/WGS84 51N投影坐标系。其他坐标系对应的代码可以查看【Python&GIS】通过经纬度创建矢量点文件

def Projection_Transform(path_input1, path_output1):
    """
    :param path_input1: 待转换的数据路径
    :param path_output1: 转换后的数据路径
    :return: None
    """
    ds_input = gdal.Open(path_input1, gdal.GA_ReadOnly)  # 打开数据集dataset
    ds = gdal.Warp(path_output1, ds_input, dstSRS="EPSG:32651", resampleAlg='cubic', callback=Show_Progress)
    # 输出路径、输入影像、目标投影、重采样方法(最邻近内插\双线性内插\三次卷积等)、回调函数
    ds.BuildOverviews(overviewlist=[2, 4, 8, 16])
    # 创建金字塔
    ds = None

三、回调函数(没啥用)

        上一篇博文已经介绍过了,就两点:1.水字数,2.记录进度。省的看着代码发呆。

def Show_Progress(percent, msg, tag):
    """
    :param percent: 进度,0~1
    :param msg:
    :param tag:
    :return:
    """
    print("开始进程......")
    if 25 <= percent*100 <= 26:
        print("进度:" + "%.2f" % (percent*100) + "%")
    if 50 <= percent*100 <= 51:
        print("进度:" + "%.2f" % (percent*100) + "%")
    if 75 <= percent*100 <= 76:
        print("进度:" + "%.2f" % (percent*100) + "%")

四、完整代码

# -*- coding: utf-8 -*-
"""
@Time : 2023/6/26 17:03
@Auth : RS迷途小书童
@File :Raster Data Projection Transform.py
@IDE :PyCharm
@Purpose :栅格数据投影/坐标转换
"""
from osgeo import gdal


def Get_data(filepath):
    ds = gdal.Open(filepath)  # 打开数据集dataset
    ds_width = ds.RasterXSize  # 获取数据宽度
    ds_height = ds.RasterYSize  # 获取数据高度
    ds_bands = ds.RasterCount  # 获取波段数
    ds_geo = ds.GetGeoTransform()  # 获取仿射地理变换参数
    ds_prj = ds.GetProjection()  # 获取投影信息
    print("影像的宽度为:" + str(ds_width))
    print("影像的高度为:" + str(ds_height))
    print("仿射地理变换参数为:" + str(ds_geo))
    print("投影坐标系为:" + str(ds_prj))
    return ds_geo
    # data = ds.ReadAsArray(0, 0, ds_width, ds_height)  # 以数组的形式读取整个数据集


def Show_Progress(percent, msg, tag):
    """
    :param percent: 进度,0~1
    :param msg:
    :param tag:
    :return:
    """
    print("开始进程......")
    if 25 <= percent*100 <= 26:
        print("进度:" + "%.2f" % (percent*100) + "%")
    if 50 <= percent*100 <= 51:
        print("进度:" + "%.2f" % (percent*100) + "%")
    if 75 <= percent*100 <= 76:
        print("进度:" + "%.2f" % (percent*100) + "%")


def Projection_Transform(path_input1, path_output1):
    """
    :param path_input1: 待转换的数据路径
    :param path_output1: 转换后的数据路径
    :return: None
    """
    ds_input = gdal.Open(path_input1, gdal.GA_ReadOnly)  # 打开数据集dataset
    ds = gdal.Warp(path_output1, ds_input, dstSRS="EPSG:32651", resampleAlg='cubic', callback=Show_Progress)
    # 输出路径、输入影像、目标投影、重采样方法(最邻近内插\双线性内插\三次卷积等)、回调函数
    ds.BuildOverviews(overviewlist=[2, 4, 8, 16])
    # 创建金字塔
    ds = None


if __name__ == "__main__":
    path_input = "B:/sharpening2_proj"
    path_output = r"B:/sharpening1.tif"
    Get_data(path_input)
    Projection_Transform(path_input, path_output)

        无论是用ENVI、ArcGIS这类软件进行的投影转换还是用Python的三方库,其实都是用一些内置的参数就行转换的,所以只适用一些常见的坐标系之间的转换。最精确的肯定还是四参数、七参数进行转换,所以只能说能转成功就皆大欢喜,转不成功就算了,强扭瓜不甜。

           如果大家在学习Python或者RS时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
以下是一个基于GDAL库的python代码,用于批量将遥感影像栅格化为矢量文件: ```python import os import glob import gdal from osgeo import ogr path = 'path/to/raster/files' output_path = 'path/to/vector/files' def raster_to_vector(raster_file, vector_file): # Open raster file and get metadata ds = gdal.Open(raster_file) band = ds.GetRasterBand(1) geotransform = ds.GetGeoTransform() proj = ds.GetProjection() cols = ds.RasterXSize rows = ds.RasterYSize # Create output shapefile and layer driver = ogr.GetDriverByName('ESRI Shapefile') out_ds = driver.CreateDataSource(vector_file) out_layer = out_ds.CreateLayer(vector_file, srs=ogr.osr.SpatialReference(proj), geom_type=ogr.wkbPolygon) # Create field for pixel value field_def = ogr.FieldDefn('Value', ogr.OFTInteger) out_layer.CreateField(field_def) # Create polygons from raster cells for y in range(rows): for x in range(cols): # Get pixel value and check if it is nodata value = band.ReadAsArray(x, y, 1, 1)[0, 0] if value == band.GetNoDataValue(): continue # Calculate polygon vertices ulx, xres, xskew, uly, yskew, yres = geotransform xcoord = ulx + (x + 0.5) * xres ycoord = uly + (y + 0.5) * yres ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(xcoord - 0.5 * xres, ycoord - 0.5 * yres) ring.AddPoint(xcoord + 0.5 * xres, ycoord - 0.5 * yres) ring.AddPoint(xcoord + 0.5 * xres, ycoord + 0.5 * yres) ring.AddPoint(xcoord - 0.5 * xres, ycoord + 0.5 * yres) ring.AddPoint(xcoord - 0.5 * xres, ycoord - 0.5 * yres) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) # Create feature and add to layer feature = ogr.Feature(out_layer.GetLayerDefn()) feature.SetGeometry(poly) feature.SetField('Value', value) out_layer.CreateFeature(feature) # Clean up ds = None out_ds = None # Loop through raster files for raster_file in glob.glob(os.path.join(path, '*.tif')): # Create output vector file name vector_file = os.path.join(output_path, os.path.splitext(os.path.basename(raster_file))[0] + '.shp') # Convert raster to vector raster_to_vector(raster_file, vector_file) ``` 这个代码将遥感影像文件夹中的所有.tif文件转换为矢量文件,输出到指定的路径下。可以根据需要对输出的矢量文件进行进一步处理,如合并、剪裁等操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RS迷途小书童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值