05-GDAL 空间分块计算-a基本思路

该博客详细介绍了如何利用GDAL库对大型遥感影像进行空间分块,以计算NDVI(归一化植被指数)。通过将图像划分为2*2的块,逐一进行计算,解决了大尺寸数据处理的效率问题。文中还讨论了如何处理奇数行列和不均匀分块,并提供了完整的Python脚本实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、空间分块思路

空间分块计算首先是将一幅较大的影像数据分成多个小块,然后分别对这些小块进行计算。这里先列举自己设想的分块的方法,后面再进一步探索多进程分块处理的方法。

比如一幅影像,拆分成2*2块tiles计算NDVI的值。
在这里插入图片描述
假如图像是400行,640列,则每块所占的行列为:
在这里插入图片描述
假设图像的存储顺序为:

data[bn,rows,cols]
波段数、行数、列数

那我们要获取的每一个分块实际上为:

data[:,begin_rows:end_rows;begin_cols:end_cols]

获取的实际上是各个波段的,这一块的数据。

二、计算思路

主要思路是先从行开始计算,i控制行,每一行内的块的rows是不变的;变动的是每一块的列cols。

比如拆分成3*3=9块,i=0控制的第一行,j遍历0,1,2;来控制列的增加。然后i+1=1,j遍历0,1,2。

所以i控制外面的大循环: c_rows为计算的平均每块图像的行数
beginrow:i*c_rows
endrow:(i+1)*c_rows j控制内部的小循环: c_cols为计算的平均每块图像的列数
begincol:j*c_cols
endcol:(j+1)*c_clos

另外还考虑到一个问题:
影像数据可能有奇数行列,或者除不尽的。这里考虑的解决办法是前面分块取小、取整。最后一行或者最后一列的分块,取到末尾行和列。

三、实现脚本代码

拆分成2*2块tiles计算NDVI的值。

from osgeo import gdal
import numpy as np

# Read Image data
dataset = gdal.Open("G:\mypython3\gdal\data\can_tmr.img")
cols = dataset.RasterXSize
rows = dataset.RasterYSize
proj=dataset.GetProjection()
im_bands = dataset.RasterCount

datas = dataset.ReadAsArray(0,0,cols,rows)
dimen = np.array(datas).shape
print(dimen)

# Get redband and NIR band
reddata = np.array(datas[2,:,:])
reddata.astype(np.float32)
nirdata = np.array(datas[3,:,:])
nirdata.astype(np.float32)
print(cols,rows)
print(np.array(reddata).shape)

# Set the tiling number,4=2*2
ntiles = 4
unittiles = int(math.sqrt(ntiles))
# Get the number of cols and rows for each tile
c_cols=int(cols/unittiles)
c_rows=int(rows/unittiles)

# Create a new dataset to store ndvi output array
outputNDVIdata = np.zeros([rows,cols],float)
print("输出ndvi栅格大小:")
print(np.array(outputNDVIdata).shape)

# Use parameter i to iterate in rows; use parameter j to iterate in cols
for i in range(unittiles):
    if i == (unittiles - 1):
        # if this is the last row
        for j in range(unittiles):
            if j == (unittiles - 1):
                # if this is the last col
                begin_rows = (c_rows) * i
                end_rows = rows
                begin_cols = (c_cols) * j
                end_cols = cols

                ndvi = (nirdata[begin_rows:end_rows, begin_cols:end_cols] - (
                    reddata[begin_rows:end_rows, begin_cols:end_cols])) / (
                               reddata[begin_rows:end_rows, begin_cols:end_cols] + nirdata[begin_rows:end_rows,
                                                                                   begin_cols:end_cols])
                outputNDVIdata[begin_rows:end_rows, begin_cols:end_cols] = ndvi

                print('i:' + str(i) + 'j:' + str(j))
                print(ndvi)
            else:
                # if this is the last row,but not the last col
                begin_rows = (c_rows) * i
                end_rows = rows
                begin_cols = (c_cols) * j
                end_cols = (j + 1) * c_cols

                ndvi = (nirdata[begin_rows:end_rows, begin_cols:end_cols] - (
                    reddata[begin_rows:end_rows, begin_cols:end_cols])) / (
                               reddata[begin_rows:end_rows, begin_cols:end_cols] + nirdata[begin_rows:end_rows,
                                                                                   begin_cols:end_cols])
                outputNDVIdata[begin_rows:end_rows, begin_cols:end_cols] = ndvi

                print('i:' + str(i) + 'j:' + str(j))
                print(ndvi)
    else:
        for j in range(unittiles):
            if j == (unittiles - 1):
                # if this is the last col, but not the last row
                begin_rows = (c_rows) * i
                end_rows = (i + 1) * c_rows
                begin_cols = (c_cols) * j
                end_cols = cols

                ndvi = (nirdata[begin_rows:end_rows, begin_cols:end_cols] - (
                    reddata[begin_rows:end_rows, begin_cols:end_cols])) / (
                               reddata[begin_rows:end_rows, begin_cols:end_cols] + nirdata[begin_rows:end_rows,
                                                                                   begin_cols:end_cols])
                outputNDVIdata[begin_rows:end_rows, begin_cols:end_cols] = ndvi

                print('i:' + str(i) + 'j:' + str(j))
                print(ndvi)
            else:
                # if this is not the last col,  not the last row neither
                begin_rows = (c_rows) * i
                end_rows = (i + 1) * c_rows
                begin_cols = (c_cols) * j
                end_cols = (j + 1) * c_cols

                ndvi = (nirdata[begin_rows:end_rows, begin_cols:end_cols] - (
                    reddata[begin_rows:end_rows, begin_cols:end_cols])) / (
                               reddata[begin_rows:end_rows, begin_cols:end_cols] + nirdata[begin_rows:end_rows,
                                                                                   begin_cols:end_cols])
                outputNDVIdata[begin_rows:end_rows, begin_cols:end_cols] = ndvi

                print('i:' + str(i) + 'j:' + str(j))
                print(ndvi)



print("输出的NDVI数组:")
print(np.array(outputNDVIdata).shape)
print(outputNDVIdata)

# Create output raster
driver = gdal.GetDriverByName("GTiff")
outDs = driver.Create("G:\mypython3\gdal\data\\ndvi.tif",cols,rows,1,gdal.GDT_Float32)
#dataset.SetProjection(proj) #写入投影
outDs.SetProjection(proj)
outBand = outDs.GetRasterBand(1)
outBand.WriteArray(outputNDVIdata)

# Close raster file
outDs = None
del outDs, outBand
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

孙同学的一个笔记本

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

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

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

打赏作者

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

抵扣说明:

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

余额充值