python:YOLO格式数据集图片和标注信息查看器
作者:CSDN @ _养乐多_
本文将介绍如何实现一个可视化图片和标签信息的查看器,代码使用python实现。点击下一张和上一张可以切换图片。
文章目录
- 一、脚本界面
- 二、完整代码
一、脚本界面
界面如下图所示,
二、完整代码
使用代码时,需要修改 class_id_to_name 还有 YOLO 格式的图片(images)文件夹路径和标签(labels)文件夹路径。
from PIL import Image, ImageDraw, ImageFont, ImageTk
import tkinter as tk
from tkinter import ttk
import os# 创建类别 ID 到中文名称的映射
class_id_to_name = {0: "飞机",1: "船只",2: "储油罐",3: "棒球场",4: "网球场",5: "篮球场",6: "跑道场地",7: "港口",8: "桥梁",9: "车辆"
}def get_image_size(image_path):# 打开图片文件with Image.open(image_path) as img:# 获取图片的宽度和高度width, height = img.sizereturn width, heightdef read_yolo_labels(label_file, img_width, img_height):with open(label_file, 'r') as file:lines = file.readlines()boxes = []for line in lines:parts = line.strip().split()class_id = int(parts[0])x_center = float(parts[1])y_center = float(parts[2])width = float(parts[3])height = float(parts[4])# 将 YOLO 格式转换为像素坐标x_center_px = int(x_center * img_width)y_center_px = int(y_center * img_height)width_px = int(width * img_width)height_px = int(height * img_height)# 计算矩形框的左上角和右下角点x1 = int(x_center_px - width_px / 2)y1 = int(y_center_px - height_px / 2)x2 = int(x_center_px + width_px / 2)y2 = int(y_center_px + height_px / 2)boxes.append((x1, y1, x2, y2, class_id))return boxesdef draw_boxes_on_image(image_path, boxes):# 使用 PIL 加载图片img = Image.open(image_path)draw = ImageDraw.Draw(img)# 定义颜色和线宽box_color = "yellow" # 选择一个亮色line_width = 5 # 设置较粗的线宽# 使用支持中文字符的系统字体try:# 尝试使用支持中文的常见系统字体font = ImageFont.truetype("msyh.ttc", size=24) # 微软雅黑except IOError:# 回退到默认字体font = ImageFont.load_default()for (x1, y1, x2, y2, class_id) in boxes:# 绘制矩形框draw.rectangle([x1, y1, x2, y2], outline=box_color, width=line_width)# 从 class_id 获取类别名称class_name = class_id_to_name.get(class_id, "未知")text = class_nametext_width, text_height = 50, 40 # 设定文本框的宽度和高度text_x = x1text_y = y1 - text_height - 5# 绘制带背景矩形的文本draw.rectangle([text_x, text_y, text_x + text_width, text_y + text_height], fill=box_color)draw.text((text_x, text_y), text, fill="black", font=font)return imgdef display_image_with_boxes(image_file, label_file):# 获取图片尺寸img_width, img_height = get_image_size(image_file)# 读取 YOLO 标签boxes = read_yolo_labels(label_file, img_width, img_height)# 在图片上绘制矩形框img_with_boxes = draw_boxes_on_image(image_file, boxes)return img_with_boxesclass ImageViewer:def __init__(self, root, image_files, label_files):self.root = rootself.image_files = image_filesself.label_files = label_filesself.current_index = 0# 设置固定的查看器大小self.viewer_width = 800self.viewer_height = 600# 初始化界面self.init_ui()def init_ui(self):self.canvas = tk.Canvas(self.root, width=self.viewer_width, height=self.viewer_height)self.canvas.pack()self.prev_button = ttk.Button(self.root, text="上一张", command=self.prev_image)self.prev_button.pack(side=tk.LEFT)self.next_button = ttk.Button(self.root, text="下一张", command=self.next_image)self.next_button.pack(side=tk.RIGHT)self.update_image()def update_image(self):image_file = self.image_files[self.current_index]label_file = self.label_files[self.current_index]img_with_boxes = display_image_with_boxes(image_file, label_file)# 将图片转换为 Tkinter 可用格式img_with_boxes = img_with_boxes.convert("RGB")img_tk = ImageTk.PhotoImage(img_with_boxes)# 计算缩放比例img_width, img_height = img_with_boxes.sizescale = min(self.viewer_width / img_width, self.viewer_height / img_height)new_width = int(img_width * scale)new_height = int(img_height * scale)# 缩放图片img_resized = img_with_boxes.resize((new_width, new_height), Image.Resampling.LANCZOS)img_tk_resized = ImageTk.PhotoImage(img_resized)# 清除画布上的内容self.canvas.delete("all")# 在画布上显示图片self.canvas.create_image(self.viewer_width / 2, self.viewer_height / 2, image=img_tk_resized)# 保持对图像的引用self.canvas.image = img_tk_resizeddef prev_image(self):if self.current_index > 0:self.current_index -= 1self.update_image()def next_image(self):if self.current_index < len(self.image_files) - 1:self.current_index += 1self.update_image()if __name__ == "__main__":# 图片和标签文件的路径image_folder = 'E:\\DataSet\\positive'label_folder = 'E:\\DataSet\\yolo_labels'# 获取所有图片和标签文件image_files = sorted([os.path.join(image_folder, f) for f in os.listdir(image_folder) if f.endswith('.jpg')])label_files = sorted([os.path.join(label_folder, f) for f in os.listdir(label_folder) if f.endswith('.txt')])# 创建 Tkinter 窗口root = tk.Tk()root.title("图片标注查看器")# 启动图像查看器viewer = ImageViewer(root, image_files, label_files)root.mainloop()
相关文章:

python:YOLO格式数据集图片和标注信息查看器
作者:CSDN _养乐多_ 本文将介绍如何实现一个可视化图片和标签信息的查看器,代码使用python实现。点击下一张和上一张可以切换图片。 文章目录 一、脚本界面二、完整代码 一、脚本界面 界面如下图所示, 二、完整代码 使用代码时࿰…...

AGI思考探究的意义、价值与乐趣 Ⅴ
搞清楚模型对知识或模式的学习与迁移对于泛化意味什么,或者说两者间的本质?相信大家对泛化性作为大语言模型LLM的突出能力已经非常了解了 - 这也是当前LLM体现出令人惊叹的通用与涌现能力的基础前提,这里不再过多赘述,但仍希望大家…...
c++: mangle命名规则
其实可用根据binutils/c++filt的源代码看。找到mangle的命名规则, 但是从网上找到了一个总结,但是github有时候上不去,摘录再次。 https://github.com/gchatelet/gcc_cpp_mangling_documentation https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling 举例: _ZN8…...

系统化学习 H264视频编码(05)码流数据及相关概念解读
说明:我们参考黄金圈学习法(什么是黄金圈法则?->模型 黄金圈法则,本文使用:why-what)来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法,理论方面会更多地讲清楚 音视频中概念的…...

【VMware】如何演示使用U盘在VMware虚拟机上安装Windows11
一、前置准备 在开始使用U盘演示在VMware虚拟机上装Windows11前,我们需要做以下前置的准备: 已制作好的Windows引导盘;WMware软件 如何制作Windows引导盘? 推荐参考: 【建议收藏】2024年最新Windows系统重装教程&…...
HanLP和Jieba区别
HanLP和Jieba都是中文分词工具,但它们在多个方面存在区别。以下是对两者区别的详细分析: 一、开发背景与语言支持 HanLP:由大连理工大学自然语言处理与社会人文计算实验室开发,是一个开源的自然语言处理工具包。它主要使用Java语…...

荒原之梦考研:考研二战会很难吗?
考研二战是不是很难,其实很大程度上取决于我们自己,我们能否认清自己的优势,能否指定和执行合理的计划,有没有强大的心理支撑等,都是决定考研二战能否成功,或者能否比较轻松的成功的关键。 在本文中&#…...

【Git企业级开发实战指南①】Git安装、基本操作!
目录 一、Git是什么?1.1特点1.2功能1.3基本概念 二、Git安装2.1Ubuntu下安装2.2Centos下安装Git 三、Git基本操作3.1创建git本地仓库3.2配置Git3.3 工作区&暂存区&版本库3.4 实操案例3.4.1添加文件 3.5 修改文件3.6版本回退3.7查看历史操作日志3.7撤销修改3…...
Leetcode 3239. Minimum Number of Flips to Make Binary Grid Palindromic I
Leetcode 3239. Minimum Number of Flips to Make Binary Grid Palindromic I 1. 解题思路2. 代码实现 题目链接:3239. Minimum Number of Flips to Make Binary Grid Palindromic I 1. 解题思路 这一题思路上的话就是分别考察一下把所有行都变成回文所需要的fli…...
C++面试基础算法的简要介绍
C是一种广泛使用的编程语言,尤其在算法和数据结构的实现中占据重要地位。以下是对C基础算法的一些介绍,涵盖了排序、查找、搜索算法以及基本的遍历算法等方面。 排序算法 快速排序(Quick Sort) 快速排序是一种分而治之的排序算法…...

【Linux网络编程】套接字Socket(UDP)
网络编程基础概念: ip地址和端口号 ip地址是网络协议地址(4字节32位,形式:xxx.xxx.xxx.xxx xxx在范围[0, 255]内),是IP协议提供的一种统一的地址格式,每台主机的ip地址不同,一个…...

jvm方法返回相关指令ireturn,areturn,return等分析
正文 看图: 做的事情如下: 1:弹出当前的方法栈帧 2:获取上一个方法 3:从当前方法的操作数栈中获取执行结果,并推送到上一个方法的操作数栈中对应的伪代码: Override public void execute(Frame frame) {Thread thread frame.thread();Frame curren…...

宝塔部署springboot vue ruoyi前后端分离项目,分离lib、resources
1、“文件”中创建好相关项目目录,并将项目相关文件传到对应目录 例如:项目名称/ #项目总目录 api/ #存放jar项目的Java项目文件 manage/ #vue管理后端界面 …...
Python 基础教程:List(列表)的使用
《Python 基础教程:List(列表)的使用》 在 Python 中,列表是最基本的数据结构之一,它是一种有序的、可变的数据集合,可以包含任意类型的元素,包括数字、字符串、其他列表等。 1. 列表的创建 …...
kubebuilder常用标签
kubebuilder 标签是用于注解 Kubernetes CRD(Custom Resource Definition) 的标签,主要用于在 Operator SDK 和 Kubebuilder 框架中生成代码、验证规则以及自定义 CRD 的生成。以下是常用的 kubebuilder 标签: 1. 字段验证标签 …...

ChatTTS文本转语音本地部署结合内网穿透实现远程使用生成AI音频
文章目录 前言1. 下载运行ChatTTS模型2. 安装Cpolar工具3. 实现公网访问4. 配置ChatTTS固定公网地址 前言 本篇文章主要介绍如何快速地在Windows系统电脑中本地部署ChatTTS开源文本转语音项目,并且我们还可以结合Cpolar内网穿透工具创建公网地址,随时随…...
基于微信小程序的高校大学生信息服务平台设计与实现
基于微信小程序的高校大学生信息服务平台设计与实现 Design and Implementation of a College Student Information Service Platform based on WeChat Mini Program 完整下载链接:基于微信小程序的高校大学生信息服务平台设计与实现 文章目录 基于微信小程序的高校大学生信息…...

YOLOV8替换Lion优化器
YOLOV8替换Lion优化器 1 优化器介绍博客 参考bilibili讲解视频 论文地址:https://arxiv.org/abs/2302.06675 代码地址:https://github.com/google/automl/blob/master/lion/lion_pytorch.py """PyTorch implementation of the Lion …...
uniapp页面里面的登录注册模板
<!-- 账号密码登录页 --> <template><view class"page"><view class"uni-content"><view class"login-logo"><image :src"logo"></image></view><text class"title title-bo…...

C++新手入门学习教程(完整版)
以下教程覆盖了 C 学习的各个方面,适合初学者循序渐进地学习。学习过程中,建议初学者多做练习和项目,以加深对理论知识的理解。希望这个教程能为你提供一个清晰的学习路径。 目录 第一章:C 简介 1.1 C 的历史与演变 1.2 C 的特…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...