遥感数据集制作(Potsdam数据集为例):TIF图像转JPG,TIF标签转PNG,图像重叠裁剪

文章目录

  • TIF图像转JPG
  • TIF标签转PNG
  • 图像重叠裁剪
  • 图像重命名
  • 数据集转COCO格式
  • 数据集转VOC格式

遥感图像不同于一般的自然图像,由于波段数量、图像位深度等原因,TIF图像数据不能使用简单的格式转换方法。本文以Potsdam数据集为例,制作能够直接用于深度学习的数据集。
Potsdam数据集的内容如下:
在这里插入图片描述
本文使用2_Ortho_RGB(图像数据RGB通道顺序)和5_Labels_all(标签数据)作为示例进行数据集制作。
在这里插入图片描述
在这里插入图片描述

TIF图像转JPG

TIF转JPG借鉴了文章怎么读取tif格式的卫星遥感数据,并将数据输入到神经网络模型中进行训练

# -*- coding: UTF-8 -*-
import numpy as np
import os
from PIL import Image
from osgeo import gdaldef readTif(imgPath, bandsOrder=[1, 2, 3]):"""读取GEO tif影像的前三个波段值,并按照R.G.B顺序存储到形状为【原长*原宽*3】的数组中:param imgPath: 图像存储全路径:param bandsOrder: RGB对应的波段顺序,如高分二号多光谱包含蓝B,绿g,红R,近红Nir外四个波段,RGB对应的波段为3,2,1:return: R.G.B三维数组"""dataset = gdal.Open(imgPath, gdal.GA_ReadOnly)cols = dataset.RasterXSizerows = dataset.RasterYSizedata = np.empty([rows, cols, 3], dtype=float)for i in range(3):band = dataset.GetRasterBand(bandsOrder[i])oneband_data = band.ReadAsArray()data[:, :, i] = oneband_datareturn datadef stretchImg(imgPath, resultPath, lower_percent=0.5, higher_percent=99.5):"""#将光谱DN值映射至0-255,并保存:param imgPath: 需要转换的tif影像路径(***.tif):param resultPath: 转换后的文件存储路径(***.jpg):param lower_percent: 低值拉伸比率:param higher_percent: 高值拉伸比率:return: 无返回参数,直接输出图片"""RGB_Array = readTif(imgPath)band_Num = RGB_Array.shape[2]JPG_Array = np.zeros_like(RGB_Array, dtype=np.uint8)for i in range(band_Num):minValue = 0maxValue = 255# 获取数组RGB_Array某个百分比分位上的值low_value = np.percentile(RGB_Array[:, :, i], lower_percent)high_value = np.percentile(RGB_Array[:, :, i], higher_percent)temp_value = minValue + (RGB_Array[:, :, i] - low_value) * (maxValue - minValue) / (high_value - low_value)temp_value[temp_value < minValue] = minValuetemp_value[temp_value > maxValue] = maxValueJPG_Array[:, :, i] = temp_valueoutputImg = Image.fromarray(np.uint8(JPG_Array))outputImg.save(resultPath)def Batch_Convert_tif_to_jpg(imgdir, savedir):# 检查保存目录是否存在,如果不存在则创建if not os.path.exists(savedir):os.makedirs(savedir)# 获取文件夹下所有tif文件名称,并存入列表file_name_list = os.listdir(imgdir)for name in file_name_list:# 获取图片文件全路径img_path = os.path.join(imgdir, name)# 获取文件名,不包含扩展名filename = os.path.splitext(name)[0]savefilename = filename + ".jpg"# 文件存储全路径savepath = os.path.join(savedir, savefilename)stretchImg(img_path, savepath)print(f"Converted {filename} to jpg format.")print("Done!")# 主函数,首先调用
if __name__ == '__main__':imgdir = r"F:\Potsdam\2_Ortho_RGB"  # tif文件所在的【文件夹】savedir = r"F:\Potsdam\jpg"  # 转为jpg后存储的【文件夹】Batch_Convert_tif_to_jpg(imgdir, savedir)

在这里插入图片描述

TIF标签转PNG

如果标签图像是单通道的,那么可以简单地进行格式转换以适应深度学习模型的输入要求。然而,当标签图像以RGB格式存在时,则需要使用RGB字典进行映射。

import os
from PIL import Image
import numpy as npdef rgb_to_single_channel(rgb_image_path, output_path, rgb_dict):"""将RGB图像转换为单通道图像,使用指定的RGB字典来映射类别标签。:param rgb_image_path: RGB图像的路径:param output_path: 转换后图像的保存路径:param rgb_dict: RGB字典,键是RGB元组,值是对应的类别标签"""# 读取RGB图像rgb_image = Image.open(rgb_image_path)# 将图像转换为numpy数组rgb_array = np.array(rgb_image)# 创建一个空的单通道图像数组single_channel_array = np.zeros((rgb_array.shape[0], rgb_array.shape[1]), dtype=np.uint8)# 将RGB值转换为单一的标量值for rgb, label in rgb_dict.items():# 将图像中的每个像素的RGB值与rgb_dict中的RGB元组进行比较# 如果匹配,则将对应的类别标签赋给单通道图像的对应像素single_channel_array[np.all(rgb_array == rgb, axis=-1)] = label# 将单通道数组转换为图像并保存single_channel_image = Image.fromarray(single_channel_array, mode='L')single_channel_image.save(output_path)def convert_tif_to_png(image_folder, output_folder, rgb_dict):"""将指定文件夹中的所有TIFF图像转换为PNG格式,并保存到另一个文件夹中。如果图像是单通道图像,则直接转换为PNG。如果图像是RGB图像,则使用rgb_to_single_channel函数进行转换。:param image_folder: 包含TIFF图像的文件夹路径。:param output_folder: 保存转换后的PNG图像的文件夹路径。:param rgb_dict: RGB字典,用于rgb_to_single_channel函数。"""# 检查输出文件夹是否存在,如果不存在则创建它if not os.path.exists(output_folder):os.makedirs(output_folder)# 遍历图像文件夹中的所有文件for filename in os.listdir(image_folder):filepath = os.path.join(image_folder, filename)# 检查文件是否为TIFF格式if filename.endswith('.tif'):try:# 打开TIFF图像image = Image.open(filepath)# 检查图像是否为单通道图像if image.mode == 'L':# 如果是单通道图像,直接转换为PNGoutput_filename = os.path.splitext(filename)[0] + '.png'output_filepath = os.path.join(output_folder, output_filename)image.save(output_filepath, 'PNG')print(f"Converted {filename} to png format.")else:# 如果是RGB图像,使用rgb_to_single_channel函数进行转换output_filename = os.path.splitext(filename)[0] + '_single_channel.png'output_filepath = os.path.join(output_folder, output_filename)rgb_to_single_channel(filepath, output_filepath, rgb_dict)print(f"Converted {filename} to single channel png format.")except Exception as e:print(f"Error converting {filename}: {str(e)}")# 指定图像文件夹和输出文件夹
image_folder = r"F:\Potsdam\5_Labels_all"
output_folder = r"F:\Potsdam\png"# 定义RGB字典
rgb_dict = {(255, 255, 255): 1,  # 不透水路面 Impervious surfaces (RGB: 255, 255, 255)(0, 0, 255): 2,      # 建筑物 Building (RGB: 0, 0, 255)(0, 255, 255): 3,    # 低植被 Low vegetation (RGB: 0, 255, 255)(0, 255, 0): 4,      # 树木 Tree (RGB: 0, 255, 0)(255, 255, 0): 5,    # 汽车 Car (RGB: 255, 255, 0)(255, 0, 0): 255       # 背景 Clutter/background (RGB: 255, 0, 0)
}# 调用函数进行转换
convert_tif_to_png(image_folder, output_folder, rgb_dict)

在这里插入图片描述

图像重叠裁剪

由于遥感图像数据集的珍贵性,我们可以使用重叠裁剪的方式扩充数据集数量,当然也可以设置为0不重叠。

import os
from PIL import Imagedef crop_images(image_path, save_path, subimage_size, overlap_ratio):"""将图像裁剪成指定大小的子图像,并允许设置子图像之间的重叠比例。只有完全覆盖原始图像的子图像才会被保存。:param image_path: 原始图像路径:param save_path: 保存子图像的路径:param subimage_size: 子图像大小(宽度和高度):param overlap_ratio: 子图像之间的重叠比例,范围在0到1之间"""# 确保保存路径存在os.makedirs(save_path, exist_ok=True)# 遍历图像路径中的所有文件for filename in os.listdir(image_path):# 检查文件是否为图像格式if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tif')):# 打开图像img = Image.open(os.path.join(image_path, filename))width, height = img.size# 计算子图像的步长,包括重叠部分step = int(subimage_size * (1 - overlap_ratio))# 计算需要划分的行列数num_rows = (height // step) + (1 if height % step > 0 else 0)num_cols = (width // step) + (1 if width % step > 0 else 0)# 遍历并保存每个子图片for row in range(num_rows):for col in range(num_cols):# 计算子图像的左上角和右下角坐标left = col * steptop = row * stepright = left + subimage_sizebottom = top + subimage_size# 检查子图像是否完全覆盖原始图像if right <= width and bottom <= height:# 裁剪子图像sub_img = img.crop((left, top, right, bottom))# 构建子图像的文件名base_name, ext = os.path.splitext(filename)sub_filename = f"{base_name}_row{row}_col{col}{ext}"# 保存子图像sub_img.save(os.path.join(save_path, sub_filename))print(f"{filename} cropping complete.")crop_images(r'F:\Potsdam\jpg',r'F:\Potsdam\jpg_512_0.5',512, 0.5)crop_images(r'F:\Potsdam\png',r'F:\Potsdam\png_512_0.5',512, 0.5)

在这里插入图片描述

图像重命名

在构建遥感图像数据集的过程中,会遇到图像集和相应的标签集在文件命名上的不一致问题。这种不一致性会导致无法直接将数据集用于深度学习模型的训练,因为模型通常需要图像和标签数据具有完全匹配的文件名,以确保它们可以正确地配对。

import osdef rename(directory, str):# 检查目录是否存在if not os.path.exists(directory):print("path error!")return# 获取目录下所有文件files = os.listdir(directory)# 循环处理每个文件for file in files:if file.endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tif')):# 检查文件名中是否包含if str in file:# 构建新的文件名new_file_name = file.replace(str, '')# 旧文件路径old_file_path = os.path.join(directory, file)# 新文件路径new_file_path = os.path.join(directory, new_file_name)try:# 重命名文件os.rename(old_file_path, new_file_path)print(f" {file} rename {new_file_name}")except Exception as e:print(f" {file} error:{e}")# 指定路径
jpg_directory_path = r"F:\Potsdam\jpg_512_0.5"
png_directory_path = r"F:\Potsdam\png_512_0.5"
jpg_str="_RGB"
png_str="_label_single_channel"# 执行重命名操作
rename(jpg_directory_path, jpg_str)
rename(png_directory_path, png_str)

在这里插入图片描述
在这里插入图片描述

数据集转COCO格式

某些深度学习模型是根据公共自然图像数据集格式进行数据集格式处理,这里给出COCO数据集的格式转化。

import os
import json
import shutil
import random
from PIL import Image# 原始JPG图片路径
jpg_path = r'F:\Five-Billion-Pixels\jpg_512'
# 原始PNG标签路径
png_path = r'F:\Five-Billion-Pixels\png_24_512'
# COCO数据集路径
coco_path = r'F:\Five-Billion-Pixels\coco-stuff'# 确保COCO数据集路径存在
if not os.path.exists(coco_path):os.makedirs(coco_path)# 创建COCO数据集的目录结构
annotations_path = os.path.join(coco_path, 'annotations')
images_path = os.path.join(coco_path, 'images')
train_images_path = os.path.join(images_path, 'train2017')
val_images_path = os.path.join(images_path, 'val2017')
train_annotations_path = os.path.join(annotations_path, 'train2017')
val_annotations_path = os.path.join(annotations_path, 'val2017')os.makedirs(annotations_path, exist_ok=True)
os.makedirs(images_path, exist_ok=True)
os.makedirs(train_images_path, exist_ok=True)
os.makedirs(val_images_path, exist_ok=True)
os.makedirs(train_annotations_path, exist_ok=True)
os.makedirs(val_annotations_path, exist_ok=True)# 获取JPG图片列表
jpg_images = [f for f in os.listdir(jpg_path) if f.lower().endswith('.jpg')]# 随机划分数据集
random.shuffle(jpg_images)
split_index = int(len(jpg_images) * 0.8)  # 80%的数据用于训练,20%的数据用于验证
train_images = jpg_images[:split_index]
val_images = jpg_images[split_index:]# 复制图像和标签到对应的目录
def copy_images_and_labels(image_list, src_image_path, src_label_path, dst_image_path, dst_label_path):for image_name in image_list:# 复制图像shutil.copy(os.path.join(src_image_path, image_name), os.path.join(dst_image_path, image_name))# 复制标签label_name = image_name.replace('.jpg', '.png')shutil.copy(os.path.join(src_label_path, label_name), os.path.join(dst_label_path, label_name))# 复制训练集图像和标签
copy_images_and_labels(train_images, jpg_path, png_path, train_images_path, train_annotations_path)# 复制验证集图像和标签
copy_images_and_labels(val_images, jpg_path, png_path, val_images_path, val_annotations_path)

数据集转VOC格式

某些深度学习模型是根据公共自然图像数据集格式进行数据集格式处理,这里给出VOC数据集的格式转化。

import os
import shutil
import randomdef create_voc_dataset(image_folder, label_folder):# 定义 VOC 数据集的主目录和子目录voc_root = 'VOCdevkit'voc_dataset = 'VOC2012'voc_images = os.path.join(voc_root, voc_dataset, 'JPEGImages')voc_labels = os.path.join(voc_root, voc_dataset, 'SegmentationClassAug')voc_image_sets = os.path.join(voc_root, voc_dataset, 'ImageSets', 'Segmentation')# 创建 VOC 数据集所需的目录结构os.makedirs(voc_images, exist_ok=True)os.makedirs(voc_labels, exist_ok=True)os.makedirs(voc_image_sets, exist_ok=True)# 遍历图像文件夹中的所有图像文件for root, dirs, files in os.walk(image_folder):for filename in files:if filename.endswith('.jpg'):# 构建图像文件的完整路径image_path = os.path.join(root, filename)# 构建 VOC 数据集中的图像路径voc_image_path = os.path.join(voc_images, filename)# 将图像复制到 VOC 数据集目录shutil.copy(image_path, voc_image_path)print('图像已复制')# 遍历标签文件夹中的所有标签文件for root, dirs, files in os.walk(label_folder):for filename in files:if filename.endswith('.png'):# 构建标签文件的完整路径label_path = os.path.join(root, filename)# 构建 VOC 数据集中的标签路径voc_label_path = os.path.join(voc_labels, filename)# 将标签复制到 VOC 数据集目录shutil.copy(label_path, voc_label_path)print('标签已复制')# 获取图像文件夹中的所有文件名(不含扩展名)image_filenames = [os.path.splitext(filename)[0] for root, dirs, files in os.walk(image_folder) for filename in files if filename.endswith('.jpg')]# 随机打乱文件名列表random.shuffle(image_filenames)# 计算训练集和验证集的分割点split_index = int(len(image_filenames) * 0.8)# 分割训练集和验证集train_files = image_filenames[:split_index]val_files = image_filenames[split_index:]# 生成 train.txt 文件train_file_path = os.path.join(voc_image_sets, 'train.txt')with open(train_file_path, 'w') as train_file:for filename in train_files:train_file.write(filename + '\n')# 生成 val.txt 文件val_file_path = os.path.join(voc_image_sets, 'val.txt')with open(val_file_path, 'w') as val_file:for filename in val_files:val_file.write(filename + '\n')# 打印成功提示信息print('train.txt 和 val.txt 已成功创建。')# 提供图像文件夹和标签文件夹的路径
image_folder = r'F:\WHDLD\Images'
label_folder = r'F:\WHDLD\Labels'# 调用函数创建 VOC 数据集
create_voc_dataset(image_folder, label_folder)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/13041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux安装配置CGAL,OpenCV和Gurobi记录

安装Qt&#xff0c;查看当前的Qt版本&#xff0c;需要至少满足v5.12 qmake -v安装CGAL&#xff0c;The Computational Geometry Algorithms Library (cgal.org) CGAL v5.6.1&#xff1a;https://github.com/CGAL/cgal/releases/download/v5.6.1/CGAL-5.6.1.tar.xz 确保C编译…

每日复盘-20240515

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 国联证券 (1)|[9:25]|[133765万]|31.12 一…

基于Pytorch深度学习神经网络MNIST手写数字识别系统源码(带界面和手写画板)

第一步&#xff1a;准备数据 mnist开源数据集 第二步&#xff1a;搭建模型 我们这里搭建了一个LeNet5网络 参考代码如下&#xff1a; import torch from torch import nnclass Reshape(nn.Module):def forward(self, x):return x.view(-1, 1, 28, 28)class LeNet5(nn.Modul…

【数据结构】C++语言实现二叉树的介绍及堆的实现(详细解读)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

分布式系统的一致性与共识算法(三)

顺序一致性(Sequential Consistency) ZooKeeper 一种说法是ZooKeeper是最终一致性&#xff0c;因为由于多副本、以及保证大多数成功的ZAB协议&#xff0c;当一个客户端进程写入一个新值&#xff0c;另外一个客户端进程不能保证马上就能读到这个值&#xff0c;但是能保证最终能…

我的第一个网页:武理天协

1. html代码 1.1 首页.html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><title>武理天协</title><link rel"stylesheet" href"./style.css"><link rel"stylesh…

【车载开发系列】SID$11服务配置

【车载开发系列】SID$11服务配置 前言 ECUReset(ECU重置),ECU作为Server端,执行Client发送来ECU Reset请求中重启的类型(通过子服务区分)。对于UDS协议关于处理该请求的逻辑,没有强制性定义。 Step1:SID和SubFunction的追加 BasicEditor→Dcm→DcmConfigSet→DcmDs…

vs2019 c++里用 typeid() . name () 与 typeid() . raw_name () 测试数据类型的区别

&#xff08;1&#xff09; 都知道&#xff0c;在 vs2019 里用 typeid 打印的类型不大准&#xff0c;会主动去掉一些修饰符&#xff0c; const 和引用 修饰符会被去掉。但也可以给咱们验证学到的代码知识提供一些参考。那么今天发现其还有 raw_name 成员函数&#xff0c;这个函…

AES分组密码

一、AES明文和密钥位数 RIJNDAEL 算法数据块长度和密钥长度都可独立地选定为大于等于 128 位且小于等于 256 位的 32 位的任意倍数。 而美国颁布 AES 时却规定数据块的长度为 128 位、密钥的长度可分别选择为 128 位&#xff0c; 192 位或 256 位 1.1 状态 中间结果叫做状态…

建模:3dmax

3Dmax 制作模型和动画&#xff08;橘肉&#xff09;&#xff1b; RizomUV 对模型进行展UV&#xff08;橘皮&#xff09;&#xff1b; Substance Painter 纹理手绘&#xff08;给橘皮制定想要的皮肤&#xff09;&#xff1b; 1.基础 1.1可编辑多边形、可编辑样条线 体、面都需要…

Polylang Pro插件下载:多语言网站构建的终极解决方案

在全球化的今天&#xff0c;多语言网站已成为企业拓展国际市场的重要工具。然而&#xff0c;创建和管理一个多语言网站并非易事。幸运的是&#xff0c;Polylang Pro插件的出现&#xff0c;为WordPress用户提供了一个强大的多语言解决方案。本文将深入探讨Polylang Pro插件的功能…

linux上git 使用方法

一、git上新建仓库 在git上新建仓库&#xff0c;并命名 二、本地初始化 //命令行 ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" //ssh查看 cd /root/.ssh/ vim rsa.pub //复制后粘贴进git网页设置里的ssh key //测试设置是否成功 ssh -T gitgithub.com/…

暴力数据结构之二叉树(堆的相关知识)

1. 堆的基本了解 堆&#xff08;heap&#xff09;是计算机科学中一种特殊的数据结构&#xff0c;通常被视为一个完全二叉树&#xff0c;并且可以用数组来存储。堆的主要应用是在一组变化频繁&#xff08;增删查改的频率较高&#xff09;的数据集中查找最值。堆分为大根堆和小根…

Spring事务的实现原理

Spring事务原理 Spring框架支持对于事务的管理功能&#xff0c;开发人员使用Spring框架能极大的简化对于数据库事务的管理操作&#xff0c;不必进行手动开启事务&#xff0c;提交事务&#xff0c;回滚事务&#xff0c;就是在配置文件或者项目的启动类配置Spring事务相关的注解…

什么是最大路径?什么是极大路径?

最近学习中&#xff0c;在这两个概念上出现了混淆&#xff0c;导致了一些误解&#xff0c;在此厘清。 最大路径 在一个简单图G中&#xff0c;u、v之间的距离 d ( u , v ) min ⁡ { u 到 v 的最短路的长度 } d(u,v) \min \{ u到v的最短路的长度 \} d(u,v)min{u到v的最短路的…

wefaf

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

使用Bash脚本和Logrotate实现Nginx日志切割

Nginx是一个广泛使用的高性能Web服务器&#xff0c;它能够处理大量的并发连接&#xff0c;但同时也会生成大量的日志文件。为了有效管理这些日志文件并确保系统的正常运行&#xff0c;我们需要定期对Nginx的日志文件进行切割和归档。本文将介绍如何使用Bash脚本和Logrotate来实…

每天Get一个小技巧:用DolphinScheduler实现隔几天调度

转载自tuoluzhe8521 这篇小短文将教会你如何使用Apache DolphinScheduler实现隔几天调度&#xff0c;有此需求的小伙伴学起来&#xff01; 1 场景分析 DolphinScheduler定时器模块-定时调度时每3秒|每3分钟|每3天这种定时&#xff0c;不能够跨分钟&#xff0c;跨小时&#x…

【C++】:string类的基本使用

目录 引言一&#xff0c;string类对象的常见构造二&#xff0c;string类对象的容量操作三&#xff0c;string类对象的访问及遍历操作四&#xff0c;string类对象的修改操作五&#xff0c;string类非成员函数六&#xff0c;整形与字符串的转换 引言 string 就是我们常说的"…

如何对SQL Server中的敏感数据进行加密解密?

为什么需要对敏感数据进行加密&#xff1f; 近几年有不少关于个人数据泄露的新闻&#xff08;个人数据通常包含如姓名、地址、身份证号码、财务信息等&#xff09;&#xff0c;给事发公司和被泄露人都带来了不小的影响。 许多国家和地区都出台了个人数据保护的法律法规&#…