python批量赋予图片坐标系及根据坐标合并图片

1. python批量赋予图片坐标系

1.1 环境条件准备

  • 相关坐标为:qgis生成的网格文件shpfile文件,获取的相关坐标
    • 每个网格都有相关坐标信息
      在这里插入图片描述
  • 赋予的图片,使用网格文件gird_256_4490.shp切割的图片
  • 赋予图片坐标系原因
    • 使用qgis切割带坐标的文件后,保存.png格式,没有了坐标信息,赋予切割图片坐标信息

1.2. 查找投影坐标系

  • 官网链接 :https://spatialreference.org/ref/
  • 输入自己要转的坐标系名称
    • 我的是China Geodetic Coordinate System 2000
    • 点击第一个链接
      在这里插入图片描述
  • 点击OGC WKT
    在这里插入图片描述
  • 复制文本**【全部复制】**
    • 将文本赋予变量img_pos_proj
      在这里插入图片描述

1.3. 相关代码

  • 图片加坐标系函数

    def def_geoCoordSys(read_path, save_name, img_transf, img_proj):
        """
    
        :param read_path: 不带坐标的图像
        :param save_name: 保存带有坐标的图像
        :param img_transf: 投影相关坐标
        :param img_proj: 投影类型
        :return:
    
        """
        array_dataset = gdal.Open(read_path)
        img_array = array_dataset.ReadAsArray(0, 0, array_dataset.RasterXSize, array_dataset.RasterYSize)
        if 'int8' in img_array.dtype.name:
            datatype = gdal.GDT_Byte
        elif 'int16' in img_array.dtype.name:
            datatype = gdal.GDT_UInt16
        else:
            datatype = gdal.GDT_Float32
    
        if len(img_array.shape) == 3:
            img_bands, im_height, im_width = img_array.shape
        else:
            img_bands, (im_height, im_width) = 1, img_array.shape
        driver = gdal.GetDriverByName("GTiff")  # 创建文件驱动
        dataset = driver.Create(
            save_name, im_width, im_height, img_bands, datatype)
        dataset.SetGeoTransform(img_transf)  # 写入仿射变换参数
        dataset.SetProjection(img_proj)  # 写入投影
    
        # 写入影像数据
        if img_bands == 1:
            dataset.GetRasterBand(1).WriteArray(img_array)
        else:
            for i in range(img_bands):
                dataset.GetRasterBand(i + 1).WriteArray(img_array[i])
        print(read_path, 'geoCoordSys get!')
    
  • 获取shpfile文件相关坐标
    在这里插入图片描述

    shpdata = gpd.read_file('data/grid.shp',encoding='utf-8')
    for j in range(0, len(shpdata)):  # 遍历网格数据
        geo = shpdata.geometry[j] # 获取坐标属性
        # ((120.78513142722576 29.253768371972182, 120.78516670362751 29.258387207528127, 120.79043393150636 29.258356166298398, 120.79039841851554 29.25373733658219, 120.78513142722576 29.253768371972182))
        # 坐标位置为:0:左上,1:左下,2:右下,3:右上,4:左上
        minX,minY=geo.__geo_interface__['coordinates'][0][1]
        maxX,maxY=geo.__geo_interface__['coordinates'][0][3]
        numX,numY=256,256  # 图片x轴像素,y轴像素
        img_pos_transf=(minX,(maxX-minX)/256 , 0.0, minY, 0.0,-(minY-maxY)/256)
        img_pos_proj = 'GEOGCS["China Geodetic Coordinate System 2000 ",DATUM["China 2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","6610"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'
        def_geoCoordSys(read_path,save_name, img_pos_transf, img_pos_proj)
    
  • 完整代码

    import os
    from osgeo import gdal
    import geopandas as gpd
    
    def def_geoCoordSys(read_path, save_name, img_transf, img_proj):
        """
    
        :param read_path: 不带坐标的图像
        :param save_name: 保存带有坐标的图像
        :param img_transf: 投影相关坐标
        :param img_proj: 投影类型
        :return:
    
        """
        array_dataset = gdal.Open(read_path)
        img_array = array_dataset.ReadAsArray(0, 0, array_dataset.RasterXSize, array_dataset.RasterYSize)
        if 'int8' in img_array.dtype.name:
            datatype = gdal.GDT_Byte
        elif 'int16' in img_array.dtype.name:
            datatype = gdal.GDT_UInt16
        else:
            datatype = gdal.GDT_Float32
    
        if len(img_array.shape) == 3:
            img_bands, im_height, im_width = img_array.shape
        else:
            img_bands, (im_height, im_width) = 1, img_array.shape
        driver = gdal.GetDriverByName("GTiff")  # 创建文件驱动
        dataset = driver.Create(
            save_name, im_width, im_height, img_bands, datatype)
        dataset.SetGeoTransform(img_transf)  # 写入仿射变换参数
        dataset.SetProjection(img_proj)  # 写入投影
        # 写入影像数据
        if img_bands == 1:
            dataset.GetRasterBand(1).WriteArray(img_array)
        else:
            for i in range(img_bands):
                dataset.GetRasterBand(i + 1).WriteArray(img_array[i])
        print(read_path, 'geoCoordSys get!')
    
    label_path=''  # 无坐标图片路径
    label_tif_path=''  # 保存有坐标图片路径
    if not os.path.exists(label_tif_path):
        os.makedirs(label_tif_path)
    data = os.walk(label_path)
    file_list=[file_list for path, folder_list, file_list in data][0]
    shpdata = gpd.read_file('grid.shp',encoding='utf-8')
    for j in range(0, len(shpdata)):
        geo = shpdata.geometry[j]
        id_name=j+1
        minX,minY=geo.__geo_interface__['coordinates'][0][1]
        maxX,maxY=geo.__geo_interface__['coordinates'][0][3]
        numX,numY=256,256  # 图片x轴像素,y轴像素
        img_pos_transf=(minX,(maxX-minX)/256 , 0.0, minY, 0.0,-(minY-maxY)/256)
        read_path=os.path.join(label_path,f'{id_name}.png')  # 无坐标图片路径·
        save_name=os.path.join(label_tif_path,f'{id_name}.tif') # 保存有坐标图片路径
        save_name=save_name.replace('png','tif')
        img_pos_proj = 'GEOGCS["China Geodetic Coordinate System 2000 ",DATUM["China 2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","6610"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'
        def_geoCoordSys(read_path,save_name, img_pos_transf, img_pos_proj)
    
    

2.python批量根据坐标合并图片并重新赋予坐标

  • 读取文件名
    dirpath = " "   # 图片文件绝对路径
    save_path= os.path.join(dirpath, 'merge_tif')  # 合并图片文件保存路径
    if not os.path.exists(save_path):
            os.makedirs(save_path)
    out_path = os.path.join(save_path, "merge.tif")
    coordinate_path=os.path.join(save_path, "coordinate_merge.tif") # 赋予合并坐标
    tif_file = glob.glob(os.path.join(dirpath, "*.tif"))  # 读取所有文件名
    
  • 将文件加入列表
    src_files_to_mosaic = []
    for tif_f in tif_file:
        src = rasterio.open(tif_f)
        src_files_to_mosaic.append(src)
    
  • 合并及文件保存
    • tif文件为灰度图片,所以我需要mosaic.reshape(mosaic.shape[1],mosaic.shape[2])
    mosaic, out_trans = merge(src_files_to_mosaic)
    Image.fromarray(mosaic.reshape(mosaic.shape[1],mosaic.shape[2]),'L').save(out_path) 
    
  • 重新赋予图片坐标
    def def_geoCoordSys(read_path, save_name,img_transf, img_proj):
            array_dataset = gdal.Open(read_path)
            img_array = array_dataset.ReadAsArray(0, 0, array_dataset.RasterXSize, array_dataset.RasterYSize)
            if 'int8' in img_array.dtype.name:
                datatype = gdal.GDT_Byte
            elif 'int16' in img_array.dtype.name:
                datatype = gdal.GDT_UInt16
            else:
                datatype = gdal.GDT_Float32
    
            if len(img_array.shape) == 3:
                img_bands, im_height, im_width = img_array.shape
            else:
                img_bands, (im_height, im_width) = 1, img_array.shape
            driver = gdal.GetDriverByName("GTiff")  # 创建文件驱动
            dataset = driver.Create(save_name, im_width, im_height, img_bands, datatype)
            dataset.SetGeoTransform(img_transf)  # 写入仿射变换参数
            dataset.SetProjection(img_proj)  # 写入投影
            if img_bands == 1:
                dataset.GetRasterBand(1).WriteArray(img_array)
            else:
                for i in range(img_bands):
                    dataset.GetRasterBand(i + 1).WriteArray(img_array[i])
            print(read_path, 'geoCoordSys get!')
    img_pos_transf=((out_trans[2],out_trans[0],0.0,out_trans[5],0.0,out_trans[4]))
    img_pos_proj = 'GEOGCS["China Geodetic Coordinate System 2000 ",DATUM["China 2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","6610"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'            
    def_geoCoordSys(out_path,coordinate_path, img_pos_transf, img_pos_proj)
    
  • 完整代码
    import os
    import glob
    import rasterio
    from osgeo import gdal
    import PIL.Image as Image
    from rasterio.merge import merge
    def def_geoCoordSys(read_path, save_name,img_transf, img_proj):
            array_dataset = gdal.Open(read_path)
            img_array = array_dataset.ReadAsArray(0, 0, array_dataset.RasterXSize, array_dataset.RasterYSize)
            if 'int8' in img_array.dtype.name:
                datatype = gdal.GDT_Byte
            elif 'int16' in img_array.dtype.name:
                datatype = gdal.GDT_UInt16
            else:
                datatype = gdal.GDT_Float32
    
            if len(img_array.shape) == 3:
                img_bands, im_height, im_width = img_array.shape
            else:
                img_bands, (im_height, im_width) = 1, img_array.shape
            driver = gdal.GetDriverByName("GTiff")  # 创建文件驱动
            dataset = driver.Create(save_name, im_width, im_height, img_bands, datatype)
            dataset.SetGeoTransform(img_transf)  # 写入仿射变换参数
            dataset.SetProjection(img_proj)  # 写入投影
            if img_bands == 1:
                dataset.GetRasterBand(1).WriteArray(img_array)
            else:
                for i in range(img_bands):
                    dataset.GetRasterBand(i + 1).WriteArray(img_array[i])
            print(read_path, 'geoCoordSys get!')
    dirpath = ""
    save_path= os.path.join(dirpath, 'merge_tif')
    if not os.path.exists(save_path):
            os.makedirs(save_path)
    out_path = os.path.join(save_path, "merge.tif")
    coordinate_path=os.path.join(save_path, "coordinate_merge.tif")
    tif_file = glob.glob(os.path.join(dirpath, "*.tif"))
    src_files_to_mosaic = []
    for tif_f in tif_file:
    	src = rasterio.open(tif_f)
    	src_files_to_mosaic.append(src)
    mosaic, out_trans = merge(src_files_to_mosaic)
    Image.fromarray(mosaic.reshape(mosaic.shape[1],mosaic.shape[2]),'L').save(out_path) 
    img_pos_transf=((out_trans[2],out_trans[0],0.0,out_trans[5],0.0,out_trans[4]))
    img_pos_proj = 'GEOGCS["China Geodetic Coordinate System 2000 ",DATUM["China 2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","6610"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'            
    def_geoCoordSys(out_path,coordinate_path, img_pos_transf, img_pos_proj)
    
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中可以使用GDAL库来读取和处理影像,并且可以使用其中的功能来批量赋予影像坐标。 首先,需要安装GDAL库,可以通过pip命令来安装。安装完毕后,需要导入相关的模块: ```python import gdal import osr ``` 接下来,可以使用gdal.Open()函数来打开影像文件: ```python dataset = gdal.Open('input_image.tif') ``` 然后,可以使用gdal.Dataset.GetProjection()函数来获取影像的投影信息: ```python geo_transform = dataset.GetGeoTransform() projection = dataset.GetProjection() ``` 接下来,可以使用osr模块来创建一个SpatialReference对象,并通过SetUTM()函数来设置UTM坐标: ```python spatial_ref = osr.SpatialReference() spatial_ref.SetUTM(zone, northern_hemisphere) ``` 然后,可以使用gdal.Dataset.SetProjection()函数来设置影像的新投影信息: ```python dataset.SetProjection(spatial_ref.ExportToWkt()) ``` 最后,可以通过gdal.Dataset.GetDriver()函数来获取输出影像的驱动类型,并使用CreateCopy()函数来创建一个新的影像副本,并将设置好的投影信息写入其中: ```python driver = gdal.GetDriverByName('GTiff') output_dataset = driver.CreateCopy('output_image.tif', dataset) output_dataset.SetProjection(spatial_ref.ExportToWkt()) ``` 以上就是使用Python批量赋予影像坐标的基本流程。可以通过循环遍历多个影像文件,将上述过程应用于每个影像文件,以实现批量赋予影像坐标的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

荼靡~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值