【教程】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个联通块重新连为一棵树。 那么最小代价是啥呢? 图解分…

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

&#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…

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剧…

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,同时不…

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

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…

SOLIDWORKS在教育领域的应用

随着科技的飞速发展和数字化浪潮的推进&#xff0c;SOLIDWORKS作为一款强大的三维设计软件&#xff0c;其应用领域已经不仅局限于工程设计和制造行业&#xff0c;还逐渐渗透到教育领域中&#xff0c;成为培养学生实践能力和创新思维的重要工具。本文将探讨SOLIDWORKS在教育领域…

【JavaEE】_Spring MVC项目获取Cookie

目录 1. Cookie与Session基础知识 1.1 Cookie与Session的区别 2. 使用servlet原生方法获取Cookie 2.2 关于λ表达式遍历法的空指针问题 2.3 Cookie的伪造 3. 使用Spring注解获取Cookie 3.1 获取单个Cookie 3.2 获取多个Cookie 1. Cookie与Session基础知识 在本专栏HTT…

CICD流水线 发布公用jar到maven私仓

3.1 发布公用jar到Maven私仓 1.选择流水线 2.新建流水线 3.选择模版 4.选择代码仓库 5. 调整构建命令 6.新增一个新阶段为 ”发送通知“&#xff0c;这里以邮件通知为例&#xff0c;保存之后&#xff0c;运行该流水线&#xff0c;对应jar就会自动发到我们私仓&#xff0c;并之…

中药配方颗粒备案信息数据库<2.5W+备案>

中药配方颗粒备案信息是指中药配方颗粒生产企业向国家药品监督管理局申报备案的相关信息。备案信息包括中药配方颗粒的名称、备案号、备案时间、备案状态、生产企业、生产地址、规格、包装、执行标准、保质期、不良反应检测、备案省局等信息。 通过对中药配方颗粒备案信息的查…

【Linux】正则表达式实验操作实例

正则表达式是一种强大的工具&#xff0c;用于在文本中查找、匹配和替换特定的字符串模式。 实验目的 掌握正则表达式的表达方式掌握grep/egrep命令的用法掌握sed 命令的用法掌握awk命令的用法 正则表达式 实验目的实验内容实验过程创建grep文件来进行如下操作用sed命令完成下列…