影像的滑动窗口裁切与拼接(附代码)

遥感影像通常尺寸较大,需要裁切成小影像块进行使用;再将处理后的小影像块拼接为原始尺寸。
这里使用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
  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值