python将tif转为png或jpg等格式

记录如何将tif格式的图像转换为png等格式

将一系列的tif格式的图像放在一个文件夹下,然后通过python代码去读图并另存为png格式(jpg格式同理,将代码中的format="PNG",改为format="JPEG"即可)代码如下:

import os
from PIL import Image

# 定义输入和输出文件夹
input_folder = "input"  # 替换为你的输入文件夹路径
output_folder = "output"  # 替换为你的输出文件夹路径

# 创建输出文件夹(如果不存在)
os.makedirs(output_folder, exist_ok=True)

# 遍历输入文件夹中的所有.tif文件
for filename in os.listdir(input_folder):
    if filename.lower().endswith(".tif"):
        input_path = os.path.join(input_folder, filename)
        output_filename = os.path.splitext(filename)[0] + ".png"
        output_path = os.path.join(output_folder, output_filename)

        try:
            # 打开图像
            image = Image.open(input_path)
            
            # 裁剪图像 (上部区域 1024x770) 一些图像可能存在无用区域可以进行裁剪,参数自定,不需要直接删掉下面两行代码
            crop_box = (0, 0, 1024, 770)  # (左, 上, 右, 下)
            image= image.crop(crop_box)

            # 保存为PNG格式
            image.save(output_path, format="PNG")
            print(f"图像 {filename} 已裁剪并保存为 {output_path}")

        except Exception as e:
            print(f"处理文件 {filename} 时出错: {e}")

希望以上代码可以帮助到大家!

<think>嗯,用户的问题是关于如何用Python将遥感RGB图片和对应的标签TIF文件裁剪成256x256的大小,同时保持标签的对应关系。我需要仔细分析他们的需求,并参考提供的引用内容来给出合适的解决方案。 首先,用户提到的引用[1]中有一个使用OpenCV裁剪图像的示例,代码里用的是cv.imread读取图像,然后通过数组切片的方式裁剪。不过这里需要注意,TIF文件可能包含地理信息,直接裁剪可能导致坐标丢失,但用户可能更关注的是像素级的对应,所以暂时可以忽略地理信息,者如果需要保留的话,可能需要用GDALrasterio来处理,但用户可能希望简化操作,所以可能优先用OpenCVPIL。 引用[3]提到了使用AffineMatrix来处理投影和坐标变换,可能涉及到更复杂的空间参考系统。但用户的问题中,重点是保持标签和图像的对应关系,所以裁剪时两者的起始点和大小必须一致。因此,关键是在裁剪图像和标签时,使用相同的起始坐标和窗口大小。 接下来,我需要考虑如何同时处理RGB图片和标签文件。标签文件可能是单通道的TIF,所以读取时需要注意保持数据类型,比如可能为uint16uint32,特别是分类标签。而RGB图片通常是8位的,所以可能需要不同的处理方式,但裁剪的方法应该是一样的。 可能的步骤包括: 1. 读取RGB图像和标签TIF文件。 2. 确定裁剪的起始坐标,比如从左上角开始,按256x256的步长滑动窗口。 3. 确保两个文件在裁剪时的窗口位置完全一致。 4. 保存裁剪后的图像和标签,并保持文件名对应,以便后续识别。 在代码实现方面,引用[1]中的cv.imread和数组切片是可行的,但要注意OpenCV读取图像时,可能会将颜色通道顺序转为BGR,所以需要转换回RGB。而标签文件如果是单通道,可能需要用GDALrasterio来正确读取,特别是如果TIF文件有多个波段其他元数据的话。不过用户提供的引用[2]中提到了将TIF转换为JPG,可能说明用户对文件格式转换有一定了解,但这里需要处理的是裁剪而非格式转换。 可能的问题点: - 如何处理不同分辨率的图像和标签?假设它们的尺寸相同,所以需要先检查两者的尺寸是否一致。 - 如何保存裁剪后的TIF标签文件,保持其原有的数据类型和可能的元数据。使用OpenCV的imwrite可能会改变数据类型压缩方式,而rasterioGDAL可能更适合处理地理空间数据,但用户可能希望用更简单的库。 因此,解决方案可能分为两种情况: 1. 如果不需要保留地理信息,仅需要像素级的对应,可以使用OpenCVPIL进行裁剪,确保裁剪的位置和大小一致。 2. 如果需要保留地理坐标信息,可能需要用rasterio来处理,调整transform和metadata。 根据用户提供的引用[3]中的代码,使用了image_ds['B2'].profile['transform']来处理坐标,这可能意味着如果用户需要保持地理信息,应该使用rasterio。但用户的问题中没有明确提到需要地理坐标,而是更关注标签和图像的对应关系。所以可能使用更简单的方法。 综上,给出一个使用OpenCV和PIL库的示例,者使用rasterio来确保正确读取和保存TIF文件。例如,读取RGB图像用OpenCV,标签用rasterio,然后进行同步裁剪。 另外,需要考虑文件遍历,比如批量处理多个图像和标签文件,确保它们的文件名对应,比如image_001.jpg对应label_001.tif。因此,在代码中需要成对处理文件,并生成对应的裁剪块。 最后,保存裁剪后的图像和标签时,命名方式要关联,例如在原文件名后加上坐标信息,方便后续匹配。</think>以下是Python实现遥感图像与标签同步裁剪为256x256的步骤: ### 方法一:基于OpenCV的像素级裁剪(无坐标保留) ```python import cv2 import os def crop_pairs(img_path, label_path, output_dir, crop_size=256): # 读取图像和标签 img = cv2.imread(img_path)[..., ::-1] # BGR转RGB label = cv2.imread(label_path, cv2.IMREAD_UNCHANGED) # 保持标签原始数据类型 # 验证尺寸一致性 assert img.shape[:2] == label.shape[:2], "图像与标签尺寸不匹配" # 创建输出目录 os.makedirs(f"{output_dir}/images", exist_ok=True) os.makedirs(f"{output_dir}/labels", exist_ok=True) # 滑动窗口裁剪 height, width = img.shape[:2] index = 0 for y in range(0, height, crop_size): for x in range(0, width, crop_size): crop_img = img[y:y+crop_size, x:x+crop_size] crop_label = label[y:y+crop_size, x:x+crop_size] # 保存成对数据 if crop_img.shape[:2] == (crop_size, crop_size): base_name = f"{os.path.basename(img_path).split('.')[0]}_{index}" cv2.imwrite(f"{output_dir}/images/{base_name}.png", crop_img[..., ::-1]) cv2.imwrite(f"{output_dir}/labels/{base_name}.tif", crop_label) index += 1 ``` ### 方法二:基于Rasterio的地理坐标裁剪(保留空间参考) ```python import rasterio from rasterio.windows import Window def georeferenced_crop(img_path, label_path, output_dir, crop_size=256): with rasterio.open(img_path) as img_src, rasterio.open(label_path) as label_src: # 验证空间参考一致性[^3] assert img_src.transform == label_src.transform, "空间参考不一致" assert img_src.shape == label_src.shape, "影像尺寸不一致" # 创建输出目录 os.makedirs(f"{output_dir}/images", exist_ok=True) os.makedirs(f"{output_dir}/labels", exist_ok=True) # 分块裁剪 height, width = img_src.shape index = 0 for y in range(0, height, crop_size): for x in range(0, width, crop_size): window = Window(x, y, crop_size, crop_size) # 读取数据 img_crop = img_src.read(window=window) label_crop = label_src.read(window=window) # 保存带地理坐标的裁剪块 if img_crop.shape[1:] == (crop_size, crop_size): profile = img_src.profile profile.update({ 'height': crop_size, 'width': crop_size, 'transform': rasterio.windows.transform(window, img_src.transform) }) base_name = f"{os.path.basename(img_path).split('.')[0]}_{index}" with rasterio.open(f"{output_dir}/images/{base_name}.tif", 'w', **profile) as dst: dst.write(img_crop) with rasterio.open(f"{output_dir}/labels/{base_name}.tif", 'w', **profile) as dst: dst.write(label_crop) index += 1 ``` ### 关键要点说明 1. **数据对齐**:必须确保$width \equiv height \equiv 0 \ (\text{mod}\ 256)$,否则边缘块需要特殊处理 2. **标签处理**:分类标签建议保存为PNG格式,数值标签推荐TIFF格式保持精度[^2] 3. **坐标保留**:方法二通过`rasterio.Window`保持空间参考系,适用于需要地理定位的场景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃金丝瓜汤的小单纯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值