【教程】VOC数据集制作

语义分割任务中VOC数据集的制作,任务中只有一种标签:gas

文章目录

  • 1、由黑白图像识别为txt标签
  • 2、txt转json
  • 3、数据集转VOC格式

1、由黑白图像识别为txt标签

由于使用CycleGAN网络进行风格迁移学习,生成了大量伪标签图像,因此需要自动提取出标签,标签格式为YOLOv8训练所需要的语义分割的标签格式
例如:提取出下图中白色的区域的标签信息
在这里插入图片描述
txt标签:
在这里插入图片描述

import os
import cv2
import numpy as np
'''
该段代码读取文件夹中的二值图像,输出白色区域的标注信息
格式为YOLOv8图像分割的txt格式
'''
def process_images(input_folder, output_folder):# 如果输出文件夹不存在,则创建它if not os.path.exists(output_folder):os.makedirs(output_folder)# 列出输入文件夹中的所有图像文件image_files = [f for f in os.listdir(input_folder) if f.endswith(('.png', '.jpg', '.jpeg', '.bmp'))]total_images = len(image_files)print(f"在文件夹'{input_folder}'中找到了 {total_images} 张图像。")# 处理每张图像for idx, filename in enumerate(image_files, 1):print(f"正在处理图像 {idx} / {total_images} : {filename}")# 加载图像image_path = os.path.join(input_folder, filename)image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)# 检查图像是否正确加载if image is None:print(f"图像 {filename} 未能正确加载。")continue# 对图像进行阈值处理以获得二值图像_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)# 寻找轮廓contours, _ = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 初始化一个列表来存储轮廓坐标contour_coordinates = []# 获取图像的尺寸以进行归一化height, width = image.shape# 遍历轮廓以提取归一化坐标for contour in contours:# 初始化一个列表来存储单个轮廓的坐标coords = ['0']  # 开头的数字0(没有小数点)for point in contour:# 归一化x和y坐标并添加到列表中x_normalized = point[0][0] / widthy_normalized = point[0][1] / heightcoords.extend([f"{x_normalized:.6f}", f"{y_normalized:.6f}"])# 将单个轮廓的坐标添加到主列表中contour_coordinates.append(' '.join(coords))# 定义输出文本文件的路径output_file_path = os.path.join(output_folder, os.path.splitext(filename)[0] + '.txt')# 将坐标写入文本文件with open(output_file_path, 'w') as file:file.write('\n'.join(contour_coordinates))
# 输入和输出文件夹路径(请替换为实际路径)
input_folder_path = 'D:\Desktop\\test0326'  # 替换为实际的输入图片文件夹
output_folder_path = 'D:\Desktop\\test0326'  # 替换为实际的输出txt标签文件夹
# 调用函数以处理图像
process_images(input_folder_path, output_folder_path)

2、txt转json

由txt文件转换为labelme标注的json格式,本人的labelme版本为5.3.1,json文件内涵图像数据,具体格式为:

json_data = {"version": "5.3.1","flags": {},"shapes": [],"imagePath": img_filename,"imageData": encoded_string,"imageHeight": height,"imageWidth": width}

代码如下:

import os
import json
import base64
from PIL import Image
import io# 文件夹路径
label_folder = 'D:\\Desktop\\Unet\\dataset\\500txt'   # txt标签文件夹
image_folder = 'D:\\Desktop\\Unet\\dataset\\500images'  # 图像文件夹
output_folder = 'D:\\Desktop\\Unet\\dataset\\500jsons'  # json标签输出的文件夹# 确保输出文件夹存在
os.makedirs(output_folder, exist_ok=True)
# 遍历文件夹中的所有 txt 文件
for filename in os.listdir(label_folder):if filename.endswith('.txt'):# 构造完整的文件路径txt_path = os.path.join(label_folder, filename)# 构造对应的图像文件路径img_filename = filename.replace('.txt', '.jpg')img_path = os.path.join(image_folder, img_filename)# 读取图像尺寸并转换为 base64with Image.open(img_path) as img:width, height = img.sizebuffered = io.BytesIO()img.save(buffered, format="JPEG")encoded_string = base64.b64encode(buffered.getvalue()).decode('utf-8')# 初始化 JSON 数据结构json_data = {"version": "5.3.1","flags": {},"shapes": [],"imagePath": img_filename,"imageData": encoded_string,"imageHeight": height,"imageWidth": width}# 读取 txt 文件并解析多边形坐标with open(txt_path, 'r') as file:for line in file:parts = line.strip().split()label_index = parts[0]  # 假设第一部分是类别索引if len(parts) < 3 or len(parts) % 2 == 0:print(f"Unexpected format in {filename}")continue# 将相对坐标转换为实际坐标(像素值)label = 'gas' if label_index == '0' else 'unknown'points = [(float(parts[i]) * width, float(parts[i + 1]) * height) for i in range(1, len(parts), 2)]shape_data = {"label": label,"points": points,"group_id": None,"description": "","shape_type": "polygon","flags": {}}json_data["shapes"].append(shape_data)# 输出 JSON 文件output_path = os.path.join(output_folder, filename.replace('.txt', '.json'))with open(output_path, 'w') as jsonfile:json.dump(json_data, jsonfile, indent=2)print(f"文件 {output_path} 已转换完成!")print("Conversion to JSON completed.")

3、数据集转VOC格式

准备好原图和json格式的标签后,转换为VOC所需的语义分割数据集
还需要准备一个labels.txt文件,里面写上所有的类别,格式如下:

__ignore__
_background_
gas

由于我的任务中只有gas这一类,所以只需要写gas,如果是多类,则依次往下添加即可,“ignore”和“background”这两行不要动,准备好labels.txt文件后还需要将路径填到下方转换代码中注明的位置:

from __future__ import print_function
import argparse
import glob
import os
import os.path as osp
import sys
import imgviz
import numpy as np
import labelmedef main(args):if osp.exists(args.output_dir):print("Output directory already exists:", args.output_dir)sys.exit(1)os.makedirs(args.output_dir)os.makedirs(osp.join(args.output_dir, "JPEGImages"))os.makedirs(osp.join(args.output_dir, "SegmentationClassnpy"))os.makedirs(osp.join(args.output_dir, "SegmentationClass"))if not args.noviz:os.makedirs(osp.join(args.output_dir, "SegmentationClassVisualization"))print("Creating dataset:", args.output_dir)class_names = []class_name_to_id = {}for i, line in enumerate(open(args.labels).readlines()):class_id = i - 1  # starts with -1class_name = line.strip()class_name_to_id[class_name] = class_idif class_id == -1:assert class_name == "__ignore__"continueelif class_id == 0:assert class_name == "_background_"class_names.append(class_name)class_names = tuple(class_names)print("class_names:", class_names)out_class_names_file = osp.join(args.output_dir, "class_names.txt")with open(out_class_names_file, "w") as f:f.writelines("\n".join(class_names))print("Saved class_names:", out_class_names_file)for filename in glob.glob(osp.join(args.input_dir, "*.json")):print("Generating dataset from:", filename)label_file = labelme.LabelFile(filename=filename)base = osp.splitext(osp.basename(filename))[0]out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg")out_lbl_file = osp.join(args.output_dir, "SegmentationClassnpy", base + ".npy")out_png_file = osp.join(args.output_dir, "SegmentationClass", base + ".png")if not args.noviz:out_viz_file = osp.join(args.output_dir,"SegmentationClassVisualization",base + ".jpg",)with open(out_img_file, "wb") as f:f.write(label_file.imageData)img = labelme.utils.img_data_to_arr(label_file.imageData)lbl, _ = labelme.utils.shapes_to_label(img_shape=img.shape,shapes=label_file.shapes,label_name_to_value=class_name_to_id,)labelme.utils.lblsave(out_png_file, lbl)np.save(out_lbl_file, lbl)if not args.noviz:viz = imgviz.label2rgb(label=lbl,# img=imgviz.rgb2gray(img),# img=img,font_size=15,label_names=class_names,loc="rb",)imgviz.io.imsave(out_viz_file, viz)def get_args():parser = argparse.ArgumentParser()parser.add_argument("--input_dir", default="D:\Desktop\\Unet\dataset\\500jsons", type=str,   ## 在这里输入json标签文件夹help="input annotated directory")parser.add_argument("--output_dir", default="D:\Desktop\\Unet\dataset\VOC500images\\", type=str,  ## 在这里输入图片文件夹 help="output dataset directory")parser.add_argument("--labels", default="D:\Desktop\\Unet\\dataset\\labels.txt", type=str,   ## 输入labels.txt文件所在的路径help="labels file")parser.add_argument("--noviz", help="no visualization", action="store_true")args = parser.parse_args()return args
if __name__ == "__main__":args = get_args()main(args)

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

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

相关文章

【递归与递推】数的计算|数的划分|耐摔指数

1.数的计算 - 蓝桥云课 (lanqiao.cn) 思路&#xff1a; 1.dfs的变量>每一次递归什么在变&#xff1f; &#xff08;1&#xff09;当前数的大小一直在变&#xff1a;sum &#xff08;2&#xff09;最高位的数&#xff1a;k 2.递归出口&#xff1a;最高位数字为1 3.注意&#…

鱼塘钓鱼(c++实现)

题目 有 N 个鱼塘排成一排&#xff0c;每个鱼塘中有一定数量的鱼&#xff0c;例如&#xff1a;N5 时&#xff0c;如下表&#xff1a; 即&#xff1a;在第 1 个鱼塘中钓鱼第 1 分钟内可钓到 10 条鱼&#xff0c;第 2 分钟内只能钓到 8 条鱼&#xff0c;……&#xff0c;第 5 分…

Codeforces Round 932 (Div. 2) ---- F. Andrey‘s Tree ---- 题解

F. Andreys Tree&#xff1a; 题目描述&#xff1a; 思路解析&#xff1a; 我们假设删除任意一个结点后&#xff0c;我们会将整个树切分为k个联通块&#xff0c;那么可以明确的知道我们只需要连接(k-1)条边就可以将这k个联通块重新连为一棵树。 那么最小代价是啥呢? 图解分…

0基础进入IT行业

0基础如何进入IT行业&#xff1f; 简介&#xff1a;对于没有任何相关背景知识的人来说&#xff0c;如何才能成功进入IT行业&#xff1f;是否有一些特定的方法或技巧可以帮助他们实现这一目标&#xff1f; 方向一&#xff1a;学习路径 对于零基础进入 IT 行业的人来说&#xff…

第十五题:最大距离

题目描述 在数列 a1,a2,⋯ ,an​中&#xff0c;定义两个元素 ai 和 aj​ 的距离为∣i−j∣∣ai−aj∣&#xff0c;即元素下标的距离加上元素值的差的绝对值&#xff0c;其中 ∣x∣ 表示 x 的绝对值。 给定一个数列&#xff0c;请问找出元素之间最大的元素距离。 输入描述 …

【网站项目】校园订餐小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

鱼骨图功能实现

dom: <div class="module-content"><div class="title"><span>[</span><p>鱼骨图</p><span>]</span></div><div class="line-mian"></div><div :ref="module + i&q…

通过UDP实现参数配置

来讲讲UDP的一种常见应用 我们知道UDP是一种无连接的网络传输协议&#xff0c;在发送数据时指定目标IP及端口就可以将数据发送出去&#xff0c;因此特别适合用作网络设备发现。 我们可以自定义一个通信端口&#xff0c;假设为55555。我们再制定一个协议用于查询目标设备&#x…

2024-04-07 作业

作业要求&#xff1a; 1> 思维导图 2> 自由发挥应用场景实现一个登录窗口界面。 【可以是QQ登录界面、也可以是自己发挥的登录界面】 要求&#xff1a;尽量每行代码都有注释 作业1&#xff1a; 作业2&#xff1a; 运行代码&#xff1a; #include "myqwidget.h&quo…

hatch,现代化的 Python 项目管理和打包工具!

目录 前言 安装 特性 基本功能 项目创建 示例代码 虚拟环境管理 依赖管理 测试 打包和发布 高级功能 插件系统 配置环境管理 自定义构建选项 集成测试工具 实际应用场景 多环境管理 持续集成与持续部署&#xff08;CI/CD&#xff09; 项目原型化 依赖与包管理 总结 前言…

Q1剧集市场复盘:2024爱优腾谁在领跑国产剧市场?

2024年Q1剧集市场的成绩单出炉了。 复盘2024年第一季度剧集市场&#xff0c;可以用“生机勃勃”四个字来形容&#xff0c;虽然和去年相比&#xff0c;今年的第一季度缺少了《狂飙》这样的头部大爆款&#xff0c;但市场大盘走势向好。 根据灯塔专业版统计&#xff0c;2024Q1剧…

4.文件上传下载

一、配置文件 Spring#上传文件使用servlet:multipart:#单个文件最大上传大小max-file-size: 10MB#每次请求上传文件大小最大值max-request-size: 30MB #自定义参数 define:nginx:path: D:\uploadFile\ 二、service层 public interface FileService {void saveFile(byte[] f…

nginx配置实例-反向代理

目录 一、目标-反向代理实现效果 二、安装tomcat 三、配置nginx服务 四、配置反向代理 一、目标-反向代理实现效果 访问过程分析&#xff1a; 二、安装tomcat 1、安装jdk环境 新建/export/server目录 解压jdk 查看是否解压成功 配置jdk软连接 进入jdk的bin目录中&#x…

echart 折线图或散点图当横坐标为小数位时,若想显示整数该如何处理?

如图当前是这样的&#xff1a; 横坐标刻度目前是小数位&#xff0c;如果直接将小数位取整则会失去精度&#xff0c;所以我们要做的是刻度即是整数&#xff0c;又能显示小数位对应的数值&#xff1b; 思路就是直接手动设置刻度&#xff1a;设置xAxis的min,max,splitNumber,同时不…

next_permutation(下一个排列)问题

模板 从后往前找到第一次降序的位置&#xff0c;将这个点换成比之前大的最小数&#xff0c;将后面的数字转变为尽量小&#xff08;转化为升序&#xff09;。 下一个排列&#xff08;LeetCode31&#xff09; class Solution { public int nextGreaterElement(int n) { Stri…

蓝桥杯-冶炼金属(二分求最大最小)

P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 二分做法&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long const int N 1e410; int n,a,b; int v[N],cnt[N]; int check(int x){for(int i1;i<n;i…

火山方舟大模型服务平台调用Demo测试(豆包)

豆包得后台大模型支持为字节得火山方舟&#xff0c;所以想使用豆包的API&#xff0c;直接从这里就可以。 一、首先注册账号&#xff1a; 火山引擎-云上增长新动力 注册完成之后&#xff0c;控制台-账户-API访问密钥 二、找到API测试用例&#xff1a; Skylark-chat API调用…

数组排序(Comparator)

题目 import java.util.Arrays; import java.util.Comparator; import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();sc.nextLine();Integer[] res new Integer[n1];//使用Integ…

让智能体像孩子一样观察别人学习动作,跨视角技能学习数据集EgoExoLearn来了

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 在探索人工智能边界时&#xff0c;我们时常惊叹于人类孩童的学习能力 —— 可以轻易地将他人…

OLAP 和 OLTP

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 OLTP与OLAP的介绍OLTP&#xff08;on-line transaction processing&#xff09;&#xff1a;联机事务处理OLAP&#xff08;On-Line Analytical Processing&#xff…