ROI裁剪--基于python
ROI裁剪--基于python
ytkz从一个大的 TIFF 图像文件中裁剪出一个小的区域,并将该区域保存为新的 TIFF 文件。这个过程通常被称为 “region of interest” (ROI) 裁剪。
在arcgis可以实现这个功能,但是如何使用代码去实现?
代码
代码短,实现了ROI裁剪影像。
from osgeo import gdal
import os
import numpy as np
from tqdm import tqdm
def saveTif(data, cols, rows, band_num, driver, proj, geoTransform, filename):
'''
@todo 保存tif文件
@param data: 数据
@param cols: 列
@param rows: 行
@param driver: 驱动
@param proj: 坐标系
@param geoTransform: 坐标转换
@param filename: 文件名
@return:
'''
outDs = driver.Create(filename, cols, rows, band_num, gdal.GDT_UInt16)
if band_num > 1:
for i in range(band_num):
outBand = outDs.GetRasterBand(i + 1)
outBand.WriteArray(data[i], 0, 0)
outBand.FlushCache()
outBand.SetNoDataValue(0)
else:
outBand = outDs.GetRasterBand(1)
outBand.WriteArray(data, 0, 0)
outBand.FlushCache()
outBand.SetNoDataValue(0)
outDs.SetProjection(proj)
outDs.SetGeoTransform(geoTransform)
outBand = None
outDs = None
class ClipTif:
def __init__(self, tiffile):
self.tiffile = tiffile
def roi_clip(self, roi= None, outpath = None):
ds = gdal.Open(self.tiffile, gdal.GA_ReadOnly)
data = ds.ReadAsArray()
transform = ds.GetGeoTransform()
proj = ds.GetProjection()
originX = transform[0]
originY = transform[3]
pixelWidth = transform[1]
pixelHeight = transform[5]
cols = ds.RasterXSize # 列数
rows = ds.RasterYSize # 行数
bandnum = ds.RasterCount
# roi = [2000, 3000, 3000, 3000] # x1,y1,dx,dy
if bandnum ==1:
temp_arr = data[roi[0]:roi[0] + roi[2], roi[1]:roi[1] + roi[3] ]
else:
temp_arr = data[:,roi[0]:roi[0] + roi[2], roi[1]:roi[1] + roi[3] ]
new_transform = (originX + roi[1] * pixelWidth, transform[1], transform[2], originY + roi[0] * pixelHeight,
transform[4], transform[5])
driver = gdal.GetDriverByName("GTiff")
name = os.path.splitext(os.path.basename(self.tiffile))[0] + '_'+str(roi[0]) + '_' + str(roi[1]) + '_' + str(roi[2]) + '_' + str(roi[3]) + '.tif'
if outpath:
if os.path.exists(outpath) == False:
os.makedirs(outpath)
else:
outpath = os.path.dirname(self.tiffile)
outfile = os.path.join(outpath, name)
# GDT_Byte = 1, GDT_UInt16 = 2, GDT_UInt32 = 4, GDT_Int32 = 5, GDT_Float32 = 6
datatype = ds.GetRasterBand(1).DataType
print("数据类型:", datatype)
saveTif(temp_arr, roi[3], roi[2], bandnum, driver, proj, new_transform, outfile, datatype = datatype)
a = 1
if __name__ == '__main__':
tiffile = r'image.tif' # 影像的全路径
roi = [5000, 4000, 10000, 10000]
ClipTif(tiffile).roi_clip(roi
以下是代码的详细解读:
- 首先,定义了一个名为
ClipTif
的类,它接收一个 TIFF 文件路径作为初始化参数。 - 在
ClipTif
类中,定义了一个名为roi_clip
的方法,它接收一个 ROI 列表和一个输出路径作为参数。ROI 列表定义了裁剪区域的起始行、起始列、行数和列数。如果没有提供输出路径,那么新的 TIFF 文件将会保存在原文件的同一目录下。 roi_clip
方法首先使用 GDAL 库打开 TIFF 文件并读取其数据和元数据,包括地理变换参数和投影信息。- 然后,它根据提供的 ROI 列表裁剪出一个小的区域。
- 接下来,它计算新的地理变换参数,这些参数将用于新的 TIFF 文件。
- 然后,它创建一个新的 TIFF 文件,并将裁剪的数据保存到其中。数据的类型(例如,字节、无符号短整数、浮点数等)与原始 TIFF 文件中的数据类型相同。
- 最后,如果你运行这个脚本(而不是导入它作为模块),那么它将会裁剪一个名为 “GF2.tif” 的 TIFF 文件中的一个区域,并将结果保存为新的 TIFF 文件。裁剪区域的参数通过
roi
列表提供。