圈圈456 2022-05-26 00:05 采纳率: 90.9%
浏览 142
已结题

python 求将栅格数据tif平均分割的代码

问题遇到的现象和发生背景

使用arcgis栅格分割功能,分割出的图像栅格无法吻合。以下是使用python代码分割的结果:

img


**红色部分并没有裁剪出,而且看样子,这部分的栅格行列号与裁剪出的行列号应该并不相同。
**

问题相关代码,请勿粘贴截图
# -*- coding: utf-8 -*-
import os
import numpy
from osgeo import gdal


class GRID:
    # 读图像文件
    def read_img(self, 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(0, 0, im_width, im_height)  # 将数据写成数组,对应栅格矩阵

        del dataset
        return im_proj, im_geotrans, im_data

    # 写文件,以写成tif为例
    def write_img(self, filename, im_proj, origin_x, origin_y, pixel_width, pixel_height, 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((origin_x, pixel_width, 0, origin_y, 0, pixel_height))  # 写入仿射变换参数
        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


# 计算某行列下像元经纬度
def calcLonLat(dataset, x, y):
    minx, xres, xskew, maxy, yskew, yres = dataset.GetGeoTransform()
    lon = minx + xres * x
    lat = maxy +xres * y
    return lon, lat


if __name__ == "__main__":
    # os.chdir(r'D:/Personality/paper/GBDT/testshiyan')  # 切换路径到待处理图像所在文件夹
    file_name = r"D:/Personality/paper/GBDT/label/dilei.tif"
    dataset = gdal.Open(file_name)
    minx, xres, xskew, maxy, yskew, yres = dataset.GetGeoTransform()
    proj, geotrans, data = GRID().read_img(file_name)  # 读数据
    print(proj)
    print(geotrans)
    print(data.shape)
    width, height = data.shape
    size = 41
    saze = 37
    for j in range(height // size):  # 切割成256*256小图
        for i in range(width // saze):
            if(j==height//saze):
                cur_image = data[i * saze:(i + 1) * saze, j * size:(j + 1) * size]
                lon = minx + xres * size * j
                lat = maxy + yres * (i * saze)
                GRID().write_img(r'D:/Personality/paper/GBDT/testshiyan/{}_{}.tif'.format(i, j), proj,
                                 lon, lat, xres, yres, cur_image)  ##写数据
            else:
                cur_image = data[i*saze:(i + 1) * saze, j * size:(j + 1) * size]
                lon=minx+xres*size*j
                lat=maxy+yres*(i*saze)
                GRID().write_img(r'D:/Personality/paper/GBDT/testshiyan/{}_{}.tif'.format(i, j), proj,
                                 lon, lat, xres, yres, cur_image)  ##写数据



运行结果及报错内容

代码没问题,正常运行。但得到的结果不理想。

我的解答思路和尝试过的方法
我想要达到的结果

我想要得到均匀分割的图像,分割出的tif具有相同的行列号。并且行列号加起来是原图像的行列号。

  • 写回答

1条回答 默认 最新

  • nanke_yh GIS领域新星创作者 2022-05-26 16:29
    关注

    从你的代码上看意思是要将tif影像分割成256×256个小图片,每个图片规模为37×41是吧?代码是这样分析出来的,但感觉与常规的分割有理念有出入。但姑且你的要求是这样的吧。那么你的height=256×41;width=256×37。

    然后我们看到第81行,j==height//saze即,判断j==256×41÷37是false的,这个分支无法进入的。
    其次,不知道你size = 41和saze = 37不知道你怎么确定的。如果影像分割刚好自己计算出来的,可以。如果并不是那怎么达到你均匀分割的要求。你需要对最右边和最下边界多余部分进行处理,首先无法满足你均匀分割的要求,然后这个多余部分处理的应该另外处理:比如增加行列数+1(因为range函数是半开区间),然后去循环判断i == width//saze,j == height//size,以此来将多余部分也保存出去。
    可以看看这篇文https://blog.csdn.net/nanke_yh/article/details/121881112
    虽然这个是C++实现的,但基本原理都一样。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月4日
  • 已采纳回答 5月27日
  • 创建了问题 5月26日

悬赏问题

  • ¥15 关于cpci总线的几个问题,有点迷糊
  • ¥15 乳腺癌数据集 相关矩阵 特征选择
  • ¥15 我的游戏账号被盗取,请问我该怎么做
  • ¥15 通关usb3.0.push文件,导致usb频繁断连
  • ¥15 有没有能解决微信公众号,只能实时拍照,没有选择相册上传功能,我不懂任何技术,,有没有给我发个软件就能搞定的方法
  • ¥15 Pythontxt文本可视化
  • ¥15 如何基于Ryu环境下使用scapy包进行数据包构造
  • ¥15 springboot国际化
  • ¥15 搭建QEMU环境运行OP-TEE出现错误
  • ¥15 Minifilter文件保护