按步长对遥感数据进行批量裁剪

2023-10-26

该代码支持多图像裁剪

先将tif格式的图片转为png

再对多个png图片进行批量裁剪

批量裁剪:

import os

# import gdal_makeData
import numpy as np
from osgeo import gdal
os.environ["OPENCV_IO_MAX_IMAGE_PIXELS"] = pow(2,40).__str__()
import cv2 as cv
from PIL import Image
from PIL import ImageFile

ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None

'''
single_cutImg函数的imread可以将输入的png格式的图片转为8位彩色后,再进行裁剪

'''
def read_gdal(path):
    """
        读取一个tiff图像
    :param path: 要读取的图像路径(包括后缀名)
    :type path: string
    :return im_data: 返回图像矩阵(h, w, c)
    :rtype im_data: numpy
    :return im_proj: 返回投影信息
    :rtype im_proj: ?
    :return im_geotrans: 返回坐标信息
    :rtype im_geotrans: ?
    """
    image = gdal.Open(path)  # 打开该图像
    if image is None:
        print(path + "文件无法打开")
        return
    img_w = image.RasterXSize  # 栅格矩阵的列数
    img_h = image.RasterYSize  # 栅格矩阵的行数
    im_bands = image.RasterCount  # 波段数
    im_proj = image.GetProjection()  # 获取投影信息
    im_geotrans = image.GetGeoTransform()  # 仿射矩阵
    im_data = image.ReadAsArray(0, 0, img_w, img_h)

    # 二值图一般是二维,需要添加一个维度
    if len(im_data.shape) == 2:
        im_data = im_data[np.newaxis, :, :]

    im_data = im_data.transpose((1, 2, 0))
    print("栅格矩阵的列数: ", img_w)
    print("栅格矩阵的行数: ", img_h)
    print("栅格矩阵的波段数: ", im_bands)
    print("栅格矩阵的投影信息: ", im_proj)
    print("栅格矩阵的仿射矩阵信息: ", im_geotrans)
    print("ia_data形状:", im_data.shape)
    return im_data, im_proj, im_geotrans


def write_gdal(im_data, path, im_proj=None, im_geotrans=None):
    """
        重新写一个tiff图像
    :param im_data: 图像矩阵(h, w, c)
    :type im_data: numpy
    :param im_proj: 要设置的投影信息(默认None)
    :type im_proj: ?
    :param im_geotrans: 要设置的坐标信息(默认None)
    :type im_geotrans: ?
    :param path: 生成的图像路径(包括后缀名)
    :type path: string
    :return: None
    :rtype: None
    """
    im_data = im_data.transpose((2, 0, 1))

    if 'int8' in im_data.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in im_data.dtype.name:
        datatype = gdal.GDT_UInt16
    elif 'float32' in im_data.dtype.name:
        datatype = gdal.GDT_Float32
    else:
        datatype = gdal.GDT_Float64
    if len(im_data.shape) == 3:
        im_bands, im_height, im_width = im_data.shape
    elif len(im_data.shape) == 2:
        im_data = np.array([im_data])
    else:
        im_bands, (im_height, im_width) = 1, im_data.shape

    # 创建文件
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(path, im_width, im_height, im_bands, datatype)
    if dataset is not None:
        if im_geotrans is None or im_proj is None:
            pass
        else:
            dataset.SetGeoTransform(im_geotrans)  # 写入仿射变换参数
            dataset.SetProjection(im_proj)  # 写入投影
    for i in range(im_bands):
        dataset.GetRasterBand(i + 1).WriteArray(im_data[i])
    del dataset


def single_set_proj_trans(ori_path, target_path):
    """
        为 target_path 影像设置 ori_path 影像的投影、坐标信息
    :param ori_path: 获取 ori_path 影像路径
    :type ori_path: string
    :param target_path: 获取 target_path 影像路径
    :type target_path: string
    :return: None
    :rtype: None
    """
    # 原图像导入
    _, im_proj, im_geotrans = read_gdal(ori_path)
    # 目标二值图导入
    im_data, _, _ = read_gdal(target_path)
    # 地理信息写入
    write_gdal(im_data, target_path, im_proj, im_geotrans)


def tif_bands_math(tif_data):
    # 读取image.tif 4bands   转换为uint16  3bands
    h, w, bands = tif_data.shape
    print("获取函数传递的tif数据为:", tif_data.shape)

    band1 = tif_data[:, :, 0]
    band2 = tif_data[:, :, 1]
    band3 = tif_data[:, :, 2]
    # band4 = tif_data[:, :, 3]
    # band5 = tif_data[:, :, 4]
    # band6 = tif_data[:, :, 5]
    # band7 = tif_data[:, :, 6]
    # band8 = tif_data[:, :, 7]

    new_tif_data = np.stack((band1, band2, band3))
    print("new_tif_data.shape::", new_tif_data.shape)
    new_tif_data = new_tif_data.transpose(1, 2, 0)
    print(new_tif_data.shape)
    new_tif_data = new_tif_data / (np.max(new_tif_data)) * 255
    new_tif_data = new_tif_data.astype(np.uint8)

    return new_tif_data


def tif_bands_math2(tif_data):
    # 读取image.tif 4bands   转换为uint16  3bands
    h, w, bands = tif_data.shape
    print("获取函数传递的tif数据为:", tif_data.shape)

    band1 = tif_data[:, :, 0]
    band2 = tif_data[:, :, 1]
    band3 = tif_data[:, :, 2]
    band4 = tif_data[:, :, 3]
    band5 = tif_data[:, :, 4]
    band6 = tif_data[:, :, 5]
    # band7 = tif_data[:, :, 6]
    # band8 = tif_data[:, :, 7]

    new_tif_data = np.stack((band1, band2, band3))
    print("new_tif_data.shape::", new_tif_data.shape)
    new_tif_data = new_tif_data.transpose(1, 2, 0)
    print(new_tif_data.shape)
    new_tif_data = new_tif_data / (np.max(new_tif_data)) * 255
    new_tif_data = new_tif_data.astype(np.uint8)

    return new_tif_data

    # a = (band4 - band3) * 1.0
    # print(type(a))
    # b = ((band4 + band3) + 0.00001)/ 1.0
    # print(type(b))
    # ndvi = a / b
    # print(type(ndvi))
    #
    # new_ndvi = ndvi / (np.max(ndvi)) * 65536
    # new_tif_data2 = np.dstack((new_ndvi, band5, band6))
    #
    # print("new_tif_data2.shape::", new_tif_data2.shape)
    # new_tif_data = np.dstack((band1, band2, band3, band4))
    # new_tif_data = np.dstack((band1, band2, band3))
    # new_tif_data = new_tif_data / (np.max(new_tif_data)) * 255
    # new_tif_data = new_tif_data.astype(np.uint8)
    # return new_tif_data


'''
ndvi
    h, w = band3.shape

    ndvi = np.zeros((h, w)).astype(np.float32)

    for i in range(h):
        for j in range(w):
            # if (band6[i][j] + band3[i][j]) == 0:
            if band6[i][j] == 0 and band3[i][j] == 0:
                # ndvi[i][j] = 0
                continue
            else:
                a = band6[i][j].astype(np.float32)
                b = band3[i][j].astype(np.float32)

                # print(ndvi[i][j], band6[i][j], band3[i][j])
                # ndvi[i][j] = (band6[i][j] - band3[i][j]).astype(np.float32) / (band6[i][j] + band3[i][j]).astype(np.float32)
                ndvi[i][j] = (a - b).astype(np.float32) / (a + b).astype(np.float32)
            # print(ndvi[i][j])

    print("ndvi最大值", np.max(ndvi))
    print("ndvi最小值", np.min(ndvi))

    # for i in range(h):
    #     for j in range(w):
    #         ndvi[i][j] = ndvi / np.max(ndvi)
    # ndvi = ((ndvi - np.min(ndvi)) / (np.max(ndvi) - np.min(ndvi))) * 255
    #
    # band5 = ((band5 - np.min(band5)) / (np.max(band5) - np.min(band5))) * 255
    # band4 = ((band4 - np.min(band4)) / (np.max(band4) - np.min(band4))) * 255
    ndvi = ((ndvi - np.min(ndvi)) / (np.max(ndvi) - np.min(ndvi)) * 255).astype(np.uint8)


    new_tif_data = np.stack((ndvi, ndvi, ndvi))
    # new_tif_data = np.stack((ndvi, band4, band5))
    print("new_tif_data.shape::", new_tif_data.shape)
    new_tif_data = new_tif_data.transpose(1, 2, 0)
    print(new_tif_data.shape)
'''


def single_tif2pngORjpg(tifPath, savePath):
    # driver = gdal.GetDriverByName('JPEG')
    driver = gdal.GetDriverByName('PNG')
    data0 = gdal.Open(tifPath)

    # data0.astype(np.byte)

    """ ERROR 6: PNG driver doesn't support data type Int16. 
    # Only eight bit (Byte) and sixteen bit (UInt16) bands supported."""

    # data1 = driver.CreateCopy(savePath, data0)
    driver.CreateCopy(savePath, data0)

    print("路径{}中单个tif数据格式转换完成。。。。。。".format(tifPath))


def tif2pngORjpg(tiffilePath, tifsavePath):
    # file_path = r"/home/dsj/dsj_Lab/lmy/Adata/zhuhaiGF/data/clipTIF/imageTIFF/"
    # save_path = r"/home/dsj/dsj_Lab/lmy/Adata/zhuhaiGF/data/JPG/"
    file_path = tiffilePath
    save_path = tifsavePath

    driver = gdal.GetDriverByName('PNG')

    files = [f for f in os.listdir(file_path) if f.endswith('.tif')]
    for each_file in files:
        file = file_path + '\\' + each_file  # 各tif数据路径全称
        fileName, fileLastName = os.path.splitext(each_file)  # 文件名, 后缀名
        oridata = gdal.Open(file)
        driver.CreateCopy(save_path + '\\' + fileName + '.png', oridata)
    print("路径{}中所有tif数据格式转换完成。。。。。。".format(file_path))


def single_cutImg(imgPath, savePath):
    #  拆分影像图的文件名称
    imgFirstName, imgLastName = os.path.splitext(imgPath)

    # img = Image.open(imgPath)
    # print(type(img))
    # print(img.size)   宽,高

    img = cv.imread(imgPath, -1)
    # print(img.dtype)
    # 第二个参数是通道数和位深的参数,
    '''
        # IMREAD_UNCHANGED = -1  # 不进行转化,比如保存为了16位的图片,读取出来仍然为16位。
        # IMREAD_GRAYSCALE = 0  # 进行转化为灰度图,比如保存为了16位的图片,读取出来为8位,类型为CV_8UC1。
        # IMREAD_COLOR = 1   # 进行转化为RGB三通道图像,图像深度转为8位
        # IMREAD_ANYDEPTH = 2  # 保持图像深度不变,进行转化为灰度图。
        # IMREAD_ANYCOLOR = 4  # 若图像通道数小于等于3,则保持原通道数不变;若通道数大于3则只取取前三个通道。图像深度转为8位
        # cv.imwrite(ResultPath1 + a + ".png", img)  # 保存为png格式
    '''

    # width, hight = img.size
    # print(img.shape)

    if len(img.shape) == 2:
        imgLabel = Image.open(imgPath)
        width, hight = imgLabel.size
    elif len(img.shape) == 3:
        hight, width, bands = img.shape


    # w = 512  # 宽度
    # h = 512  # 高度



    w = 512
    h = 512

    _id = 1  # 裁剪结果保存文件名:0 - N 升序方式
    y = 0
    while y + h <= hight:  # 控制高度,图像多余固定尺寸总和部分不要了
        x = 0
        while x + w <= width:  # 控制宽度,图像多余固定尺寸总和部分不要了
            # new_img = img.crop((x, y, x + w, y + h))
            # new_img.save(ResultPath + a + "_" + str(_id) + b)
            # new_img.save(savePath + '\\' + 'img' + "_" + str(_id) + imgLastName)

            if len(img.shape) == 2:
                new_img = imgLabel.crop((x, y, x + w, y + h))
                # new_img.save(ResultPath + a + "_" + str(_id) + b)
                # values, counts = np.unique(new_img, return_counts=True)
                new_img.save(savePath + '\\' + 'img' + "_" + str(_id) + imgLastName)
                # new_img = img[y: y+h, x: x+w]
            elif len(img.shape) == 3:
                new_img = img[y: y + h, x: x + w, :]
                # values, counts = np.unique(new_img, return_counts=True)
                cv.imwrite(savePath + '\\' + "img_" + str(_id) + '.png', new_img)

            _id += 1
            x += w
        y = y + h

def cutImg_Slide(imgPath, savePath, image_size, stride):
    #  拆分影像图的文件名称
    imgFirstName, imgLastName = os.path.splitext(imgPath)
    img = cv.imread(imgPath, -1)

    if len(img.shape) == 2:
        height, width = img.shape
    elif len(img.shape) == 3:
        height, width, bands = img.shape

    _id = 0  # 裁剪结果保存文件名:0 - N 升序方式
    h_num = int(height / stride)
    w_num = int(width / stride)
    print(h_num)
    print(w_num)

    for i in range(0, h_num):
        for j in range(0, w_num):
            if i * stride + image_size <= height and j * stride + image_size <= width:
                if len(img.shape) == 2:
                    new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size]
                    cv.imwrite(savePath + '\\' + "img_" + str(_id) + '.png', new_img)
                elif len(img.shape) == 3:
                    new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size, :]
                    cv.imwrite(savePath + '\\' + "img_" + str(_id) + '.png', new_img)
            _id += 1


def cutImg_Slide_2(file_path, save_path, image_size, stride):

    files = [f for f in os.listdir(file_path) if f.endswith('.png')]
    _num = 1
    for each_file in files:
        file = file_path + '\\' + each_file  # 各tif数据路径全称
        fileName, fileLastName = os.path.splitext(each_file)  # 文件名, 后缀名
        #oridata = gdal.Open(file)
        #driver.CreateCopy(save_path + '\\' + fileName + '.png', oridata)

        #  拆分影像图的文件名称
        imgFirstName, imgLastName = os.path.splitext(file)
        img = cv.imread(file, -1)

        if len(img.shape) == 2:
            height, width = img.shape
        elif len(img.shape) == 3:
            height, width, bands = img.shape

        _id = 0  # 裁剪结果保存文件名:0 - N 升序方式
        h_num = int(height / stride)
        w_num = int(width / stride)
        print(h_num)
        print(w_num)

        for i in range(0, h_num):
            for j in range(0, w_num):
                if i * stride + image_size <= height and j * stride + image_size <= width:
                    if len(img.shape) == 2:
                        new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size]
                        cv.imwrite(save_path + '\\' + "img_" +str(_num) +"_img_" + str(_id) + '.png', new_img)
                    elif len(img.shape) == 3:
                        new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size, :]
                        cv.imwrite(save_path + '\\' +"img_" +str(_num) +"_img_" + str(_id) +'.png', new_img)
                _id += 1
        _num+=1




    #
    # #  拆分影像图的文件名称
    # imgFirstName, imgLastName = os.path.splitext(imgPath)
    # img = cv.imread(imgPath, -1)
    #
    # if len(img.shape) == 2:
    #     height, width = img.shape
    # elif len(img.shape) == 3:
    #     height, width, bands = img.shape
    #
    # _id = 0  # 裁剪结果保存文件名:0 - N 升序方式
    # h_num = int(height / stride)
    # w_num = int(width / stride)
    # print(h_num)
    # print(w_num)
    #
    # for i in range(0, h_num):
    #     for j in range(0, w_num):
    #         if i * stride + image_size <= height and j * stride + image_size <= width:
    #             if len(img.shape) == 2:
    #                 new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size]
    #                 cv.imwrite(savePath + '\\' + "img_" + str(_id) + '.png', new_img)
    #             elif len(img.shape) == 3:
    #                 new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size, :]
    #                 cv.imwrite(savePath + '\\' + "img_" + str(_id) + '.png', new_img)
    #         _id += 1



def makeTIFF(tif_dir, tif_saveDir):
    tif_data, tif_proj, tif_geotrans = read_gdal(tif_dir)
    print("读取的tif数据为:", tif_data.shape)

    new_tif_data = tif_bands_math(tif_data)

    write_gdal(new_tif_data, tif_saveDir, tif_proj, tif_geotrans)


if __name__ == '__main__':

    # path = r'E:\New_gj\dataset\T0\data_pre\labels\label_1.tif'
    # img, _, _ = read_gdal(path)
    #
    # values, counts = np.unique(img, return_counts=True)
    # print(values)
    # print(counts)
    # exit()

    path = r'E:\New_gj\dataset\T_multi_22\data_pre'  #图像路径
    dataset_path = r'E:\New_gj\dataset\T_multi_22\cut'  #存储路径

    # img
    #读取tif bands   转换为3bands
    #tif_dir = r'E:\New_gj\dataset\T2\data_pre\images\image.tif'
    #tif_saveDir = path + r'\images\image.tif'   #三波段图片名
    #makeTIFF(tif_dir, tif_saveDir)  #转三波段

    tif_saveDir=path + r'\images'
    pngORjpg_path = path + r'\images\png'  # png,jpg存储路径
    # tif转格式  路径不要出现中文
    #pngORjpg_path = path + r'\images\image.png'  #png,jpg存储路径
    #single_tif2pngORjpg(tif_saveDir, pngORjpg_path)

    tif2pngORjpg(tif_saveDir, pngORjpg_path)



    # 裁剪
    image_size = 512#输出尺寸
    stride = 512
    pngORjpg_savePath = dataset_path + r'\images_pre'  #保存路径
    cutImg_Slide_2(pngORjpg_path, pngORjpg_savePath, image_size, stride)


    # -------------------------------------------------------------------------------
    # label
    tif_saveDir_label = path + r'\labels'
    pngORjpg_path_label = path + r'\labels\png'
    #single_tif2pngORjpg(tif_saveDir_label, pngORjpg_path_label)
    tif2pngORjpg(tif_saveDir_label, pngORjpg_path_label)

    pngORjpg_savePath_label = dataset_path + r'\labels_pre'
    cutImg_Slide_2(pngORjpg_path_label, pngORjpg_savePath_label, image_size, stride)

单张图片裁剪

import os

# import gdal_makeData
import numpy as np
from osgeo import gdal
os.environ["OPENCV_IO_MAX_IMAGE_PIXELS"] = pow(2,40).__str__()
import cv2 as cv
from PIL import Image
from PIL import ImageFile

ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None

'''
single_cutImg函数的imread可以将输入的png格式的图片转为8位彩色后,再进行裁剪

'''
def read_gdal(path):
    """
        读取一个tiff图像
    :param path: 要读取的图像路径(包括后缀名)
    :type path: string
    :return im_data: 返回图像矩阵(h, w, c)
    :rtype im_data: numpy
    :return im_proj: 返回投影信息
    :rtype im_proj: ?
    :return im_geotrans: 返回坐标信息
    :rtype im_geotrans: ?
    """
    image = gdal.Open(path)  # 打开该图像
    if image is None:
        print(path + "文件无法打开")
        return
    img_w = image.RasterXSize  # 栅格矩阵的列数
    img_h = image.RasterYSize  # 栅格矩阵的行数
    im_bands = image.RasterCount  # 波段数
    im_proj = image.GetProjection()  # 获取投影信息
    im_geotrans = image.GetGeoTransform()  # 仿射矩阵
    im_data = image.ReadAsArray(0, 0, img_w, img_h)

    # 二值图一般是二维,需要添加一个维度
    if len(im_data.shape) == 2:
        im_data = im_data[np.newaxis, :, :]

    im_data = im_data.transpose((1, 2, 0))
    print("栅格矩阵的列数: ", img_w)
    print("栅格矩阵的行数: ", img_h)
    print("栅格矩阵的波段数: ", im_bands)
    print("栅格矩阵的投影信息: ", im_proj)
    print("栅格矩阵的仿射矩阵信息: ", im_geotrans)
    print("ia_data形状:", im_data.shape)
    return im_data, im_proj, im_geotrans


def write_gdal(im_data, path, im_proj=None, im_geotrans=None):
    """
        重新写一个tiff图像
    :param im_data: 图像矩阵(h, w, c)
    :type im_data: numpy
    :param im_proj: 要设置的投影信息(默认None)
    :type im_proj: ?
    :param im_geotrans: 要设置的坐标信息(默认None)
    :type im_geotrans: ?
    :param path: 生成的图像路径(包括后缀名)
    :type path: string
    :return: None
    :rtype: None
    """
    im_data = im_data.transpose((2, 0, 1))

    if 'int8' in im_data.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in im_data.dtype.name:
        datatype = gdal.GDT_UInt16
    elif 'float32' in im_data.dtype.name:
        datatype = gdal.GDT_Float32
    else:
        datatype = gdal.GDT_Float64
    if len(im_data.shape) == 3:
        im_bands, im_height, im_width = im_data.shape
    elif len(im_data.shape) == 2:
        im_data = np.array([im_data])
    else:
        im_bands, (im_height, im_width) = 1, im_data.shape

    # 创建文件
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(path, im_width, im_height, im_bands, datatype)
    if dataset is not None:
        if im_geotrans is None or im_proj is None:
            pass
        else:
            dataset.SetGeoTransform(im_geotrans)  # 写入仿射变换参数
            dataset.SetProjection(im_proj)  # 写入投影
    for i in range(im_bands):
        dataset.GetRasterBand(i + 1).WriteArray(im_data[i])
    del dataset


def single_set_proj_trans(ori_path, target_path):
    """
        为 target_path 影像设置 ori_path 影像的投影、坐标信息
    :param ori_path: 获取 ori_path 影像路径
    :type ori_path: string
    :param target_path: 获取 target_path 影像路径
    :type target_path: string
    :return: None
    :rtype: None
    """
    # 原图像导入
    _, im_proj, im_geotrans = read_gdal(ori_path)
    # 目标二值图导入
    im_data, _, _ = read_gdal(target_path)
    # 地理信息写入
    write_gdal(im_data, target_path, im_proj, im_geotrans)


def tif_bands_math(tif_data):
    # 读取image.tif 4bands   转换为uint16  3bands
    h, w, bands = tif_data.shape
    print("获取函数传递的tif数据为:", tif_data.shape)

    band1 = tif_data[:, :, 0]
    band2 = tif_data[:, :, 1]
    band3 = tif_data[:, :, 2]
    # band4 = tif_data[:, :, 3]
    # band5 = tif_data[:, :, 4]
    # band6 = tif_data[:, :, 5]
    # band7 = tif_data[:, :, 6]
    # band8 = tif_data[:, :, 7]

    new_tif_data = np.stack((band1, band2, band3))
    print("new_tif_data.shape::", new_tif_data.shape)
    new_tif_data = new_tif_data.transpose(1, 2, 0)
    print(new_tif_data.shape)
    new_tif_data = new_tif_data / (np.max(new_tif_data)) * 255
    new_tif_data = new_tif_data.astype(np.uint8)

    return new_tif_data


def tif_bands_math2(tif_data):
    # 读取image.tif 4bands   转换为uint16  3bands
    h, w, bands = tif_data.shape
    print("获取函数传递的tif数据为:", tif_data.shape)

    band1 = tif_data[:, :, 0]
    band2 = tif_data[:, :, 1]
    band3 = tif_data[:, :, 2]
    band4 = tif_data[:, :, 3]
    band5 = tif_data[:, :, 4]
    band6 = tif_data[:, :, 5]
    # band7 = tif_data[:, :, 6]
    # band8 = tif_data[:, :, 7]

    new_tif_data = np.stack((band1, band2, band3))
    print("new_tif_data.shape::", new_tif_data.shape)
    new_tif_data = new_tif_data.transpose(1, 2, 0)
    print(new_tif_data.shape)
    new_tif_data = new_tif_data / (np.max(new_tif_data)) * 255
    new_tif_data = new_tif_data.astype(np.uint8)

    return new_tif_data

    # a = (band4 - band3) * 1.0
    # print(type(a))
    # b = ((band4 + band3) + 0.00001)/ 1.0
    # print(type(b))
    # ndvi = a / b
    # print(type(ndvi))
    #
    # new_ndvi = ndvi / (np.max(ndvi)) * 65536
    # new_tif_data2 = np.dstack((new_ndvi, band5, band6))
    #
    # print("new_tif_data2.shape::", new_tif_data2.shape)
    # new_tif_data = np.dstack((band1, band2, band3, band4))
    # new_tif_data = np.dstack((band1, band2, band3))
    # new_tif_data = new_tif_data / (np.max(new_tif_data)) * 255
    # new_tif_data = new_tif_data.astype(np.uint8)
    # return new_tif_data


'''
ndvi
    h, w = band3.shape

    ndvi = np.zeros((h, w)).astype(np.float32)

    for i in range(h):
        for j in range(w):
            # if (band6[i][j] + band3[i][j]) == 0:
            if band6[i][j] == 0 and band3[i][j] == 0:
                # ndvi[i][j] = 0
                continue
            else:
                a = band6[i][j].astype(np.float32)
                b = band3[i][j].astype(np.float32)

                # print(ndvi[i][j], band6[i][j], band3[i][j])
                # ndvi[i][j] = (band6[i][j] - band3[i][j]).astype(np.float32) / (band6[i][j] + band3[i][j]).astype(np.float32)
                ndvi[i][j] = (a - b).astype(np.float32) / (a + b).astype(np.float32)
            # print(ndvi[i][j])

    print("ndvi最大值", np.max(ndvi))
    print("ndvi最小值", np.min(ndvi))

    # for i in range(h):
    #     for j in range(w):
    #         ndvi[i][j] = ndvi / np.max(ndvi)
    # ndvi = ((ndvi - np.min(ndvi)) / (np.max(ndvi) - np.min(ndvi))) * 255
    #
    # band5 = ((band5 - np.min(band5)) / (np.max(band5) - np.min(band5))) * 255
    # band4 = ((band4 - np.min(band4)) / (np.max(band4) - np.min(band4))) * 255
    ndvi = ((ndvi - np.min(ndvi)) / (np.max(ndvi) - np.min(ndvi)) * 255).astype(np.uint8)


    new_tif_data = np.stack((ndvi, ndvi, ndvi))
    # new_tif_data = np.stack((ndvi, band4, band5))
    print("new_tif_data.shape::", new_tif_data.shape)
    new_tif_data = new_tif_data.transpose(1, 2, 0)
    print(new_tif_data.shape)
'''


def single_tif2pngORjpg(tifPath, savePath):
    # driver = gdal.GetDriverByName('JPEG')
    driver = gdal.GetDriverByName('PNG')
    data0 = gdal.Open(tifPath)

    # data0.astype(np.byte)

    """ ERROR 6: PNG driver doesn't support data type Int16. 
    # Only eight bit (Byte) and sixteen bit (UInt16) bands supported."""

    # data1 = driver.CreateCopy(savePath, data0)
    driver.CreateCopy(savePath, data0)

    print("路径{}中单个tif数据格式转换完成。。。。。。".format(tifPath))


def tif2pngORjpg(tiffilePath, tifsavePath):
    # file_path = r"/home/dsj/dsj_Lab/lmy/Adata/zhuhaiGF/data/clipTIF/imageTIFF/"
    # save_path = r"/home/dsj/dsj_Lab/lmy/Adata/zhuhaiGF/data/JPG/"
    file_path = tiffilePath
    save_path = tifsavePath

    driver = gdal.GetDriverByName('PNG')

    files = [f for f in os.listdir(file_path) if f.endswith('.tif')]
    for each_file in files:
        file = file_path + each_file  # 各tif数据路径全称
        fileName, fileLastName = os.path.splitext(each_file)  # 文件名, 后缀名
        oridata = gdal.Open(file)
    data = driver.CreateCopy(save_path + 'zhuhai_' + fileName + '.png', oridata)
    print("路径{}中所有tif数据格式转换完成。。。。。。".format(file_path))


def single_cutImg(imgPath, savePath):
    #  拆分影像图的文件名称
    imgFirstName, imgLastName = os.path.splitext(imgPath)

    # img = Image.open(imgPath)
    # print(type(img))
    # print(img.size)   宽,高

    img = cv.imread(imgPath, -1)
    # print(img.dtype)
    # 第二个参数是通道数和位深的参数,
    '''
        # IMREAD_UNCHANGED = -1  # 不进行转化,比如保存为了16位的图片,读取出来仍然为16位。
        # IMREAD_GRAYSCALE = 0  # 进行转化为灰度图,比如保存为了16位的图片,读取出来为8位,类型为CV_8UC1。
        # IMREAD_COLOR = 1   # 进行转化为RGB三通道图像,图像深度转为8位
        # IMREAD_ANYDEPTH = 2  # 保持图像深度不变,进行转化为灰度图。
        # IMREAD_ANYCOLOR = 4  # 若图像通道数小于等于3,则保持原通道数不变;若通道数大于3则只取取前三个通道。图像深度转为8位
        # cv.imwrite(ResultPath1 + a + ".png", img)  # 保存为png格式
    '''

    # width, hight = img.size
    # print(img.shape)

    if len(img.shape) == 2:
        imgLabel = Image.open(imgPath)
        width, hight = imgLabel.size
    elif len(img.shape) == 3:
        hight, width, bands = img.shape


    # w = 512  # 宽度
    # h = 512  # 高度



    w = 512
    h = 512

    _id = 1  # 裁剪结果保存文件名:0 - N 升序方式
    y = 0
    while y + h <= hight:  # 控制高度,图像多余固定尺寸总和部分不要了
        x = 0
        while x + w <= width:  # 控制宽度,图像多余固定尺寸总和部分不要了
            # new_img = img.crop((x, y, x + w, y + h))
            # new_img.save(ResultPath + a + "_" + str(_id) + b)
            # new_img.save(savePath + '\\' + 'img' + "_" + str(_id) + imgLastName)

            if len(img.shape) == 2:
                new_img = imgLabel.crop((x, y, x + w, y + h))
                # new_img.save(ResultPath + a + "_" + str(_id) + b)
                # values, counts = np.unique(new_img, return_counts=True)
                new_img.save(savePath + '\\' + 'img' + "_" + str(_id) + imgLastName)
                # new_img = img[y: y+h, x: x+w]
            elif len(img.shape) == 3:
                new_img = img[y: y + h, x: x + w, :]
                # values, counts = np.unique(new_img, return_counts=True)
                cv.imwrite(savePath + '\\' + "img_" + str(_id) + '.png', new_img)

            _id += 1
            x += w
        y = y + h

def cutImg_Slide(imgPath, savePath, image_size, stride):
    #  拆分影像图的文件名称
    imgFirstName, imgLastName = os.path.splitext(imgPath)
    img = cv.imread(imgPath, -1)

    if len(img.shape) == 2:
        height, width = img.shape
    elif len(img.shape) == 3:
        height, width, bands = img.shape

    _id = 0  # 裁剪结果保存文件名:0 - N 升序方式
    h_num = int(height / stride)
    w_num = int(width / stride)
    print(h_num)
    print(w_num)

    for i in range(0, h_num):
        for j in range(0, w_num):
            if i * stride + image_size <= height and j * stride + image_size <= width:
                if len(img.shape) == 2:
                    new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size]
                    cv.imwrite(savePath + '\\' + imgFirstName + "_img_" + str(_id) + '.png', new_img)
                elif len(img.shape) == 3:
                    new_img = img[i * stride: i * stride + image_size, j * stride: j * stride + image_size, :]
                    cv.imwrite(savePath + '\\' + imgFirstName +"_img_" + str(_id) + '.png', new_img)
            _id += 1


def makeTIFF(tif_dir, tif_saveDir):
    tif_data, tif_proj, tif_geotrans = read_gdal(tif_dir)
    print("读取的tif数据为:", tif_data.shape)

    new_tif_data = tif_bands_math(tif_data)

    write_gdal(new_tif_data, tif_saveDir, tif_proj, tif_geotrans)


if __name__ == '__main__':

    # path = r'E:\New_gj\dataset\T0\data_pre\labels\label_1.tif'
    # img, _, _ = read_gdal(path)
    #
    # values, counts = np.unique(img, return_counts=True)
    # print(values)
    # print(counts)
    # exit()

    path = r'E:\New_gj\dataset\T_multi_re_0.1\predict'  #图像路径
    dataset_path = r'E:\New_gj\dataset\T_multi_re_0.1\predict\cut'  #存储路径

    # img
    #读取tif bands   转换为3bands
    #tif_dir = r'E:\New_gj\dataset\T2\data_pre\images\image.tif'
    tif_saveDir = path + r'\images\image_2.tif'   #三波段图片名
    #makeTIFF(tif_dir, tif_saveDir)  #转三波段


    # tif转格式  路径不要出现中文
    pngORjpg_path = path + r'\images\png\image_2.png'  #png,jpg存储路径
    single_tif2pngORjpg(tif_saveDir, pngORjpg_path)

    # 裁剪
    image_size = 512#输出尺寸
    stride = 512
    pngORjpg_savePath = dataset_path + r'\images'  #保存路径
    cutImg_Slide(pngORjpg_path, pngORjpg_savePath, image_size, stride)


    # -------------------------------------------------------------------------------
    # label
    tif_saveDir_label = path + r'\labels\label_2.tif'
    pngORjpg_path_label = path + r'\labels\png\label_2.png'
    single_tif2pngORjpg(tif_saveDir_label, pngORjpg_path_label)


    pngORjpg_savePath_label = dataset_path + r'\labels'
    cutImg_Slide(pngORjpg_path_label, pngORjpg_savePath_label, image_size, stride)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按步长对遥感数据进行批量裁剪 的相关文章

  • Python - 比较同一字典中的值

    我有一本字典 d Trump MAGA FollowTheMoney Clinton dems Clinton Stein FollowTheMoney Atlanta 我想删除字符串列表中的重复字符串 该字符串是键的值 对于这个例子 期望
  • 让 VoiceChannel.members 和 Guild.members 返回完整列表的问题

    每当我尝试使用 VoiceChannel members 或 Guild members 时 它都不会提供适用成员的完整列表 我从文本命令的上下文中获取 VoiceChannel 和 Guild 如下所示 bot command name
  • Gunicorn 工作人员无论如何都会超时

    我正在尝试通过gunicorn运行一个简单的烧瓶应用程序 但是无论我做什么 我的工作人员都会超时 无论是否有针对应用程序的活动 工作人员在我设置任何内容后总是会超时timeout值到 是什么导致它们超时 当我发出请求时 请求成功通过 但工作
  • matplotlib 图中点的标签

    所以这是一个关于已发布的解决方案的问题 我试图在我拥有的 matplotlib 散点图中的点上放置一些数据标签 我试图在这里模仿解决方案 是否有与 MATLAB 的 datacursormode 等效的 matplotlib https s
  • pandas DataFrame.join 的运行时间是多少(大“O”顺序)?

    这个问题更具概念性 理论性 与非常大的数据集的运行时间有关 所以我很抱歉没有一个最小的例子来展示 我有一堆来自两个不同传感器的数据帧 我需要最终将它们连接成两个very来自两个不同传感器的大数据帧 df snsr1 and df snsr2
  • 多输出堆叠回归器

    一次性问题 我正在尝试构建一个多输入堆叠回归器 添加到 sklearn 0 22 据我了解 我必须结合StackingRegressor and MultiOutputRegressor 经过多次尝试 这似乎是正确的顺序 import nu
  • PyQt 使用 ctrl+Enter 触发按钮

    我正在尝试在我的应用程序中触发 确定 按钮 我当前尝试的代码是这样的 self okPushButton setShortcut ctrl Enter 然而 它不起作用 这是有道理的 我尝试查找一些按键序列here http ftp ics
  • Pycharm 在 os.path 连接上出现“未解析的引用”

    将pycharm升级到2018 1 并将python升级到3 6 5后 pycharm报告 未解析的引用 join 最新版本的 pycharm 不会显示以下行的任何警告 from os path import join expanduser
  • 打印数字时添加千位分隔符[重复]

    这个问题在这里已经有答案了 我真的不知道这个问题的 名称 所以它可能是一个不正确的标题 但问题很简单 如果我有一个数字 例如 number 23543 second 68471243 我想要它使print 像这样 23 54368 471
  • 矩形函数的数值傅里叶变换

    本文的目的是通过一个众所周知的分析傅里叶变换示例来正确理解 Python 或 Matlab 上的数值傅里叶变换 为此 我选择矩形函数 这里报告了它的解析表达式及其傅立叶变换https en wikipedia org wiki Rectan
  • Django 视图中的“请求”是什么

    在 Django 第一个应用程序的 Django 教程中 我们有 from django http import HttpResponse def index request return HttpResponse Hello world
  • 如何将 GAE 中一种 Kind 中的所有实体复制到另一种 Kind 中,而无需显式调用每个属性

    我们如何使用function clone entity 如中所述在 Python 中复制 Google App Engine 数据存储中的实体 而无需在 编译 时知道属性名称 https stackoverflow com question
  • Pandas 组合不同索引的数据帧

    我有两个数据框df 1 and df 2具有不同的索引和列 但是 有一些索引和列重叠 我创建了一个数据框df索引和列的并集 因此不存在重复的索引或列 我想填写数据框df通过以下方式 for x in df index for y in df
  • 如何使用 Python 3 检查目录是否包含文件

    我到处寻找这个答案但找不到 我正在尝试编写一个脚本来搜索特定的子文件夹 然后检查它是否包含任何文件 如果包含 则写出该文件夹的路径 我已经弄清楚了子文件夹搜索部分 但检查文件却难倒了我 我发现了有关如何检查文件夹是否为空的多个建议 并且我尝
  • 如何使用 AWS Lambda Python 读取 AWS S3 存储的 Word 文档(.doc 和 .docx)文件内容?

    我的场景是 我尝试使用 python 实现从 Aws Lambda 读取 AWS 存储的 S3 word 文档 doc 和 docx 文件内容 下面的代码是我使用的 我的问题是我可以获取文件名 但无法读取内容 def lambda hand
  • Python:Goslate 翻译请求返回“503:服务不可用”[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我们不允许提出寻求书籍 工具 软件库等推荐的问题 您可以编辑问题 以便用事实和引文来回答 这个问题似乎不是关于主要由程序员使用的特定编程问
  • Firebase Firestore:获取文档的生成 ID (Python)

    我可以创建一个新文档 带有自动生成的 ID 并存储对其的引用 如下所示 my data key value doc ref db collection u campaigns add my data 我可以像这样访问数据本身 print d
  • 如何在 Flask 中的视图函数/会话之间传递复杂对象

    我正在编写一个 Web 应用程序 当 且仅当 用户登录时 该应用程序从第三方服务器接收大量数据 这些数据被解析为自定义对象并存储在list 现在 用户在应用程序中使用这些数据 调用不同的视图 例如发送不同的请求 我不确定什么是最好的模式在视
  • 将索引与值交换的最快方法

    考虑pd Series s s pd Series list abcdefghij list ABCDEFGHIJ s A a B b C c D d E e F f G g H h I i J j dtype object 交换索引和值并
  • JSON:TypeError:Decimal('34.3')不是JSON可序列化的[重复]

    这个问题在这里已经有答案了 我正在运行一个 SQL 查询 它返回一个小数列表 当我尝试将其转换为 JSON 时 出现类型错误 查询 res db execute SELECT CAST SUM r SalesVolume 1000 0 AS

随机推荐

  • 数据结构笔记 第六章 查找技术

    查找技术 在计算机科学中定义为 在一些 有序的 无序的 数据元素中 通过一定的方法找出与给定关键字相同的数据元素的过程叫做查找 也就是根据给定的某个值 在查找表中确定一个关键字等于给定值的记录或数据元素 线性表的查找技术 顺序查找 顺序查找
  • 【报名中】【5G探索】深度揭秘5G核心技术与挑战,云+社区开发者大会北京站等你来!

    报名渠道 扫描下方二维码 开发者专属福利 限量手办 现场幸运签到开发者即可获得 早到获奖几率更大 幸运抽奖 一等奖 1名 JBL LIVE650 BTNC无线主动降噪智能耳机 二等奖 3名 JBL GO SMART2 音乐魔方二代便携式人工
  • Thread类常见方法及属性及线程的状态

    本篇文章思维导图如下 目录 Thread构造方法 Thread常见属性 守护线程 start 方法 创建一个线程 中断线程 总结一下interrupt方法 等待线程 join 休眠线程sleep 线程的状态 Thread构造方法 Threa
  • 实验一 以太网组建

    实验一 以太网组建 一 实验目的和要求 1 认识交换机和路由器的结构与连接方法 2 区分直通线和交叉 3 掌握简单的局域网配置方法以及组网方法 4 了解ip地址的组成 5 了解子网掩码 MAC 默认网关 数据链路地址的概念 6 了解配置路由
  • 区块链到底是什么?

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 翻译人 ArrayZoneYour 该成员来自云 社区翻译社 原文链接 https www investinblockchain com what exactly is blockc
  • 936焊台(恒温电烙铁)温度不可调的维修 (Z)

    Original Address http www zhaoniupai com archives 162 html 1 产线送来一台深圳山寨白光SBK 936焊台 恒温电烙铁 温度高且不可调 即使旋回220最低温度处 烙铁的温度也很高 锡
  • Maven 常用配置

    常用命令 打包指定模块 跳过测试 mvn clean package pl web am Dmaven test skip true 打包并构建docker镜像 详情参考 https blog csdn net u014438244 art
  • 地理坐标系和投影坐标系之间的关系

    转自 http blog csdn net qq 34149805 article details 65634252 基本概念 地理坐标系 为球面坐标 参考平面地是椭球面 坐标单位 经纬度 投影坐标系 为平面坐标 参考平面地是水平面 坐标单
  • C# 串口接收1次数据会进入2次串口接收事件serialPort1_DataReceived,第2次进入时串口缓冲区为空

    在C 中使用串口接收数据时发现 在完整的接收完一次数据后 还会再次进入串口接收事件 在网上搜索资料发现其他开发者也有遇到该问题 1 c 串口事件接受一次数据莫名其妙会触发两次 原文链接 https www 52pojie cn thread
  • 剑指Offer 06.从尾到头打印链表

    原题链接 思路 首先扫描一遍链表 算出链表中有多少个元素 再一次扫描链表 映射到数组的相应位置上就行 如果说 链表中 3 个元素 第一个元素对应的位置就是 2 第二个元素对应的位置就是 1 第三个元素对应的位置就是 0 代码 class S
  • UGUI聊天消息气泡随文本内容自适应

    游戏中需要用做UGUI做聊天界面 其中聊天气泡ChatItem的UI要求能随着聊天内容文本的长度自适应的 网上搜了一下聊天气泡的UI 发现都不太符合咱的需求 具体来说是文本宽度不足一行时 文本宽度自增 文本宽度大于一行时 文本高度自增 效果
  • 大数据导论学习日志Day1

    第一章大数据概述 1数据 1 1数据的概念 数据是指对客观事件进行记录并可以鉴别的符号 是对客观事物的性质 状态以及相互关系等进行记载的物理符号或这些物理符号的组合 是可识别的 抽象的符号 数据和信息是两个不同的概念 信息是较为宏观的概念
  • mysql 唯一索引为null_mysql 唯一索引与null.md

    mysql 的唯一索引要求所有参与的列都不能够为 null 值 如果唯一索引中的任何一个元素含有 null 值 则唯一约束将不起作用 示例代码 create table tb a int b int c int unique index a
  • go并发爬虫

    说明 最大20线程 搜索深度不大于3的网页 并打印出来 当搜索的不是网页的时候 存在bug 还在学习 希望有大佬告知怎么解决 package main import fmt log net http golang org x net htm
  • ReactNative系列之三十一业务bundle拆分及动态加载实例

    2018 12 17日志 1 github上的源代码更新 修复windows上生成bundle内路径的异常处理 暂时先放出思路 近期会做一期视频解析及源码下载 敬请关注 演示视频 https pan baidu com s 1FYVYgSe
  • http请求 状态码204

    今天在调试接口的时候遇到个问题 一个请求走了两次 一次204 一次200 且 请求204的 Request Method 是 OPTIONS 在网上查看资料后得知 是因为跨域而引起的 OPTIONS是一种 预检请求 浏览器在处理跨域访问的请
  • 【C++】基础语法7--继承

    继承 意义 增加代码利用率 语法 class 类名1 权限 父类2 类名1被称为 子类 或者 派生类 类名2被称为 父类 或者 基类 class dog public class Taidi public dog 继承方式 公共继承方式 p
  • 刷脸支付成功路上任何事都需要经过历练

    刷脸支付自出世以来 争议从未断过 有人认为刷脸支付十分安全便捷 是可以替代扫码支付的支付方式首选 也有人认为刷脸支付会泄露人脸信息造成安全隐患从而拒绝使用 关于刷脸支付安全性 支付宝微信早已出面解释并表示刷脸支付十分安全 也承诺若有因刷脸支
  • 一步一步学习openfire+spark(1)

    以前写过一篇关于openfire的文章 内容比较孤立 写的也比较简单 没有实际意义 正好公司使用的是这个平台 现在从新开始 对openfire这个框架进行系统性的学习 深入的了解openfire以及和openfire配套的spark的开发
  • 按步长对遥感数据进行批量裁剪

    该代码支持多图像裁剪 先将tif格式的图片转为png 再对多个png图片进行批量裁剪 批量裁剪 import os import gdal makeData import numpy as np from osgeo import gdal