遥感影像通常尺寸较大,需要裁切成小影像块进行使用;再将处理后的小影像块拼接为原始尺寸。
这里使用python进行影像的裁剪与拼接。(单通道影像,多通道修改即可)
影像的自动裁切
按照窗口进行滑动裁切,往往最后一行或一列裁切不到,这里考虑最后无法完整裁切的情况,最后一行或一列的裁切不满足窗口的大小则向上或向左取像素行或列。
如图,待裁剪图像尺寸56,裁剪窗口22,步长为0;
行可以完全裁切,列剩最后一列不能完全裁切,此时裁切窗口如绿色框所示。
'''
读取遥感影像可以使用gdal,也可以使用cv。
'''
# 读取tif数据集 方法1
def readTif(fileName):
dataset = gdal.Open(fileName)
if dataset == None:
print(fileName + "文件无法打开")
return dataset
# 读取tif数据集 方法2
def get_data(path_name):
img_size = 24
img_names = os.listdir(path_name)
img_names.sort(key=lambda x: int(x[:-4]))
T1 = []
num = len(img_names)
for i in range(num):
img_name = img_names[i]
img = cv.imread(path_name+img_name, cv.IMREAD_UNCHANGED)
img = img.reshape([img_size, img_size,1])
T1.append(img)
T1 = np.array(T1)
return T1
'''
滑动窗口裁剪函数
TifPath 影像路径
SavePath 裁剪后保存目录
CropSize 裁剪尺寸
RepetitionSize 步长
'''
def TifCrop(TifPath, SavePath, CropSize, RepetitionSize):
dataset_img = readTif(TifPath)
width = dataset_img.RasterXSize
height = dataset_img.RasterYSize
proj = dataset_img.GetProjection()
geotrans = dataset_img.GetGeoTransform()
img = dataset_img.ReadAsArray(0, 0, width, height) # 获取数据,ndarray
# 获取当前文件夹的文件个数len,并以len+1命名即将裁剪得到的图像
new_name = len(os.listdir(SavePath))
for i in range(int((height - RepetitionSize) / (CropSize - RepetitionSize))):
for j in range(int((width - RepetitionSize) / (CropSize - RepetitionSize))):
# 如果图像是单波段
if (len(img.shape) == 2):
cropped = img[
int(i * (CropSize - RepetitionSize)): int(i * (CropSize - RepetitionSize)) + CropSize,
int(j * (CropSize - RepetitionSize)): int(j * (CropSize - RepetitionSize)) + CropSize]
# 如果图像是多波段
else:
cropped = img[:,
int(i * (CropSize - RepetitionSize)): int(i * (CropSize - RepetitionSize)) + CropSize,
int(j * (CropSize - RepetitionSize)): int(j * (CropSize - RepetitionSize)) + CropSize]
# 写图像
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
# 文件名 + 1
new_name = new_name + 1
# 裁剪最后一列
for i in range(int((height - RepetitionSize) / (CropSize - RepetitionSize))):
if (len(img.shape) == 2):
cropped = img[int(i * (CropSize - RepetitionSize)): int(i * (CropSize - RepetitionSize)) + CropSize,
(width - CropSize): width]
else:
cropped = img[:,
int(i * (CropSize - RepetitionSize)): int(i * (CropSize - RepetitionSize)) + CropSize,
(width - CropSize): width]
# 写图像
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
new_name = new_name + 1
# 裁剪最后一行
for j in range(int((width - RepetitionSize) / (CropSize - RepetitionSize))):
if (len(img.shape) == 2):
cropped = img[(height - CropSize): height,
int(j * (CropSize - RepetitionSize)): int(j * (CropSize - RepetitionSize)) + CropSize]
else:
cropped = img[:,
(height - CropSize): height,
int(j * (CropSize - RepetitionSize)): int(j * (CropSize - RepetitionSize)) + CropSize]
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
# 文件名 + 1
new_name = new_name + 1
# 裁剪右下角最后一个影像块
if (len(img.shape) == 2):
cropped = img[(height - CropSize): height,
(width - CropSize): width]
else:
cropped = img[:,
(height - CropSize): height,
(width - CropSize): width]
writeTiff(cropped, geotrans, proj, SavePath + "/%d.tif" % new_name)
影像拼接,过程与裁剪相反。这里给出单波段的代码
def TifMosaic(TifPath, CropSize, RepetitionSize):
height = 143
width = 248
result = np.zeros((height,width),float)
imgs = get_data(TifPath)
imgs = np.squeeze(imgs)
n = 0
for i in range(int((height - RepetitionSize) / (CropSize - RepetitionSize))):
for j in range(int((width - RepetitionSize) / (CropSize - RepetitionSize))):
result[int(i * (CropSize - RepetitionSize)): int(i * (CropSize - RepetitionSize)) + CropSize,
int(j * (CropSize - RepetitionSize)): int(j * (CropSize - RepetitionSize)) + CropSize] = imgs[n]
n = n+1
# 拼接最后一列
for i in range(int((height - RepetitionSize) / (CropSize - RepetitionSize))):
result[int(i * (CropSize - RepetitionSize)): int(i * (CropSize - RepetitionSize)) + CropSize,
(width - CropSize): width] = imgs[n]
n = n+1
# 拼接最后一行
for j in range(int((width - RepetitionSize) / (CropSize - RepetitionSize))):
result[(height - CropSize): height,
int(j * (CropSize - RepetitionSize)): int(j * (CropSize - RepetitionSize)) + CropSize] = imgs[n]
n = n+1
# 拼接最后一个小块
result[(height - CropSize): height,
(width - CropSize): width] = imgs[n]
return result