数据集学习笔记(六):目标检测和图像分割标注软件介绍和使用,并转换成YOLO系列可使用的数据集格式

文章目录

  • 一、目标检测
    • 1.1 labelImg
    • 1.2 介绍
    • 1.3 安装
    • 1.4 使用
    • 1.5 转换
    • 1.6 验证
  • 二、图像分割
    • 2.1 labelme
    • 2.2 介绍
    • 2.3 安装
    • 2.4 使用
    • 2.5 转换
    • 2.6 验证

一、目标检测

1.1 labelImg

1.2 介绍

labelImg是一个开源的图像标注工具,用于创建图像标注数据集。它提供了一个简单易用的界面,允许用户通过绘制边界框或者创建多边形来标注图像中的对象。它支持多种常见的标注格式,如Pascal VOC、YOLO和COCO等。

使用labelImg,用户可以加载图像文件夹,逐个标注图像中的对象,并保存标注结果。该工具还提供了一些快捷键和功能,如缩放、移动和删除标注框,以及快速切换到下一张图像等。此外,labelImg还支持标注图像的困难程度、部分可见性和关键点等。

labelImg是一个跨平台的工具,可以在Windows、Linux和macOS等操作系统上运行。它基于Python和Qt开发,可以通过pip安装或从GitHub上获取源代码。这使得用户可以根据自己的需求进行定制和扩展。

总而言之,labelImg是一个功能强大、易于使用的图像标注工具,适用于创建各种类型的标注数据集,从而用于训练和评估计算机视觉模型。

1.3 安装

pip install labelImg

1.4 使用

  • 在cmd中输入labelImg,打开目标标注界面
    在这里插入图片描述
  • open dir选择图片的文件夹、Change Save Dir选择label保存的位置、在View下选择auto save mode可以不用每次都要点击保存、在File里面选择YOLO数据集的格式(点击pascalVOC切换)。
  • 通过w来选择标注区域,然后写上类别名
  • 键盘输入a是上一张,d是下一张
  • 然后按照这种格式将图片和label进行分开(train和valid同理)

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

1.5 转换

如果通过labelImg直接得到txt标签文本是不用进行转换就可以提供给YOLO进行训练的。
如果是保存的XML文本,则需要通过下面代码进行转换。

修改两个路径:xml文件地址和创建保存txt文件的地址

import os
import xml.etree.ElementTree as ET# xml文件存放目录(修改成自己的文件名)
input_dir = r'E:\auto_label\annotation'# 输出txt文件目录(自己创建的文件夹)
out_dir = r'E:\auto_label\labels'class_list = []# 获取目录所有xml文件
def file_name(input_dir):F = []for root, dirs, files in os.walk(input_dir):for file in files:# print file.decode('gbk')    #文件名中有中文字符时转码if os.path.splitext(file)[1] == '.xml':t = os.path.splitext(file)[0]F.append(t)  # 将所有的文件名添加到L列表中return F  # 返回L列表# 获取所有分类
def get_class(filelist):for i in filelist:f_dir = input_dir + "\\" + i + ".xml"in_file = open(f_dir, encoding='UTF-8')filetree = ET.parse(in_file)in_file.close()root = filetree.getroot()for obj in root.iter('object'):cls = obj.find('name').textif cls not in class_list:class_list.append(cls)def ConverCoordinate(imgshape, bbox):# 将xml像素坐标转换为txt归一化后的坐标xmin, xmax, ymin, ymax = bboxwidth = imgshape[0]height = imgshape[1]dw = 1. / widthdh = 1. / heightx = (xmin + xmax) / 2.0y = (ymin + ymax) / 2.0w = xmax - xminh = ymax - ymin# 归一化x = x * dwy = y * dhw = w * dwh = h * dhreturn x, y, w, hdef readxml(i):f_dir = input_dir + "\\" + i + ".xml"txtresult = ''outfile = open(f_dir, encoding='UTF-8')filetree = ET.parse(outfile)outfile.close()root = filetree.getroot()# 获取图片大小size = root.find('size')width = int(size.find('width').text)height = int(size.find('height').text)imgshape = (width, height)# 转化为yolov5的格式for obj in root.findall('object'):# 获取类别名obj_name = obj.find('name').textobj_id = class_list.index(obj_name)# 获取每个obj的bbox框的左上和右下坐标bbox = obj.find('bndbox')xmin = float(bbox.find('xmin').text)xmax = float(bbox.find('xmax').text)ymin = float(bbox.find('ymin').text)ymax = float(bbox.find('ymax').text)bbox_coor = (xmin, xmax, ymin, ymax)x, y, w, h = ConverCoordinate(imgshape, bbox_coor)txt = '{} {} {} {} {}\n'.format(obj_id, x, y, w, h)txtresult = txtresult + txt# print(txtresult)f = open(out_dir + "\\" + i + ".txt", 'a')f.write(txtresult)f.close()# 获取文件夹下的所有文件
filelist = file_name(input_dir)# 获取所有分类
get_class(filelist)# 打印class
print(class_list)# xml转txt
for i in filelist:readxml(i)# 在out_dir下生成一个class文件
f = open(out_dir + "\\classes.txt", 'a')
classresult = ''
for i in class_list:classresult = classresult + i + "\n"
f.write(classresult)
f.close()

1.6 验证

import cv2
import os# 读取txt文件信息
def read_list(txt_path):pos = []with open(txt_path, 'r') as file_to_read:while True:lines = file_to_read.readline()  # 整行读取数据if not lines:break# 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。p_tmp = [float(i) for i in lines.split(' ')]pos.append(p_tmp)  # 添加新读取的数据# Efield.append(E_tmp)passreturn pos# txt转换为box
def convert(size, box):xmin = (box[1] - box[3] / 2.) * size[1]xmax = (box[1] + box[3] / 2.) * size[1]ymin = (box[2] - box[4] / 2.) * size[0]ymax = (box[2] + box[4] / 2.) * size[0]box = (int(xmin), int(ymin), int(xmax), int(ymax))return boxdef draw_box_in_single_image(image_path, txt_path):# 读取图像image = cv2.imread(image_path)pos = read_list(txt_path)for i in range(len(pos)):label = classes[int(str(int(pos[i][0])))]print('label is '+label)box = convert(image.shape, pos[i])image = cv2.rectangle(image,(box[0], box[1]),(box[2],box[3]),colores[int(str(int(pos[i][0])))],2)cv2.putText(image, label,(box[0],box[1]-2), 0, 1, colores[int(str(int(pos[i][0])))], thickness=2, lineType=cv2.LINE_AA)cv2.imshow("images", image)cv2.waitKey(0)if __name__ == '__main__':img_folder = "D:\datasets\YOLO/images"img_list = os.listdir(img_folder)img_list.sort()label_folder = "D:\datasets\YOLO/labels"label_list = os.listdir(label_folder)label_list.sort()classes = {0: "cat", 1: "dog"}colores = [(0,0,255),(255,0,255)]for i in range(len(img_list)):image_path = img_folder + "\\" + img_list[i]txt_path = label_folder + "\\" + label_list[i]draw_box_in_single_image(image_path, txt_path)

在这里插入图片描述

二、图像分割

2.1 labelme

2.2 介绍

LabelMe是一个在线图像标注工具,旨在帮助用户对图像进行标注和注释。它提供了一个简单易用的界面,让用户可以方便地在图像上绘制边界框、标记点、线条等,并为每个标注对象添加文字描述。

LabelMe的主要特点包括

  • 灵活多样的标注工具:LabelMe提供了多种标注工具,包括矩形框、多边形、线条、点等,可以满足不同类型图像的标注需求。

  • 支持多种标注任务:LabelMe适用于各种标注任务,包括对象检测、语义分割、关键点标注等。

  • 数据的可视化和管理:LabelMe支持将标注结果可视化展示,用户可以在网页上查看和编辑标注结果。此外,LabelMe还提供了数据管理功能,可以方便地组织和管理大量的标注数据。

  • 数据的导入和导出:LabelMe支持将标注数据导入和导出为常见的数据格式,如XML、JSON等,方便与其他机器学习和计算机视觉工具集成。

总的来说,LabelMe是一个功能强大且易于使用的在线图像标注工具,适用于各种图像标注任务,并提供了方便的数据管理和导入导出功能。

2.3 安装

pip install labelme -i https://pypi.tuna.tsinghua.edu.cn/simple/

2.4 使用

参考链接:点击
在这里插入图片描述
打完标签后,会在我们图片的目录下相应的生成JSON标签文件,首先我们先验证一下我们打的标签和图片是否对应,如果没问题那么我们才转换成YOLO可训练的标签文件。参考代码如下:

import os, cv2, json
import numpy as npbase_path = '../dataset/labelme_dataset'
path_list = [i.split('.')[0] for i in os.listdir(base_path) if 'json' in i]
print(path_list)
for path in path_list:image = cv2.imread(f'{base_path}/{path}.jpg')h, w, c = image.shapelabel = np.zeros((h, w), dtype=np.uint8)with open(f'{base_path}/{path}.json') as f:mask = json.load(f)['shapes']for i in mask:i = np.array([np.array(j) for j in i['points']])label = cv2.fillPoly(label, [np.array(i, dtype=np.int32)], color=255)image = cv2.bitwise_and(image, image, mask=label)cv2.imshow('Pic', image)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

2.5 转换

既然打的标签文件是没问题的,那么我们开始转换成YOLO可用的TXT文件,转换代码如下:

import os, cv2, json
import numpy as npclasses = ['square', 'triangle'] # 修改成对应的类别base_path = '../dataset/labelme_dataset' # 指定json和图片的位置
path_list = [i.split('.')[0] for i in os.listdir(base_path)]
for path in path_list:image = cv2.imread(f'{base_path}/{path}.jpg')h, w, c = image.shapewith open(f'{base_path}/{path}.json') as f:masks = json.load(f)['shapes']with open(f'{base_path}/{path}.txt', 'w+') as f:for idx, mask_data in enumerate(masks):mask_label = mask_data['label']if '_' in mask_label:mask_label = mask_label.split('_')[0]mask = np.array([np.array(i) for i in mask_data['points']], dtype=np.float)mask[:, 0] /= wmask[:, 1] /= hmask = mask.reshape((-1))if idx != 0:f.write('\n')f.write(f'{classes.index(mask_label)} {" ".join(list(map(lambda x:f"{x:.6f}", mask)))}')

通过这个代码可以在当前目录生成对应文件名的TXT标签文件,然后我们需要将其划分为训练集、验证集和测试集,可通过下面的代码:

import os, shutil, random
import numpy as nppostfix = 'jpg' # 里面都是jpg图片
base_path = '../dataset/labelme_dataset' # 原图片和TXT文件
dataset_path = '../dataset/custom_dataset' # 保存的目标位置
val_size, test_size = 0.1, 0.2os.makedirs(dataset_path, exist_ok=True)
os.makedirs(f'{dataset_path}/images', exist_ok=True)
os.makedirs(f'{dataset_path}/images/train', exist_ok=True)
os.makedirs(f'{dataset_path}/images/val', exist_ok=True)
os.makedirs(f'{dataset_path}/images/test', exist_ok=True)
os.makedirs(f'{dataset_path}/labels/train', exist_ok=True)
os.makedirs(f'{dataset_path}/labels/val', exist_ok=True)
os.makedirs(f'{dataset_path}/labels/test', exist_ok=True)path_list = np.array([i.split('.')[0] for i in os.listdir(base_path) if 'txt' in i])
random.shuffle(path_list)
train_id = path_list[:int(len(path_list) * (1 - val_size - test_size))]
val_id = path_list[int(len(path_list) * (1 - val_size - test_size)):int(len(path_list) * (1 - test_size))]
test_id = path_list[int(len(path_list) * (1 - test_size)):]for i in train_id:shutil.copy(f'{base_path}/{i}.{postfix}', f'{dataset_path}/images/train/{i}.{postfix}')shutil.copy(f'{base_path}/{i}.txt', f'{dataset_path}/labels/train/{i}.txt')for i in val_id:shutil.copy(f'{base_path}/{i}.{postfix}', f'{dataset_path}/images/val/{i}.{postfix}')shutil.copy(f'{base_path}/{i}.txt', f'{dataset_path}/labels/val/{i}.txt')for i in test_id:shutil.copy(f'{base_path}/{i}.{postfix}', f'{dataset_path}/images/test/{i}.{postfix}')shutil.copy(f'{base_path}/{i}.txt', f'{dataset_path}/labels/test/{i}.txt')

2.6 验证

通过结合TXT标签文件以及图片来进行可视化,以验证其是否正确。

import os, cv2
import numpy as npimg_base_path = '../dataset/custom_dataset/images/train'
lab_base_path = '../dataset/custom_dataset/labels/train'label_path_list = [i.split('.')[0] for i in os.listdir(img_base_path)]
for path in label_path_list:image = cv2.imread(f'{img_base_path}/{path}.jpg')h, w, c = image.shapelabel = np.zeros((h, w), dtype=np.uint8)with open(f'{lab_base_path}/{path}.txt') as f:mask = np.array(list(map(lambda x:np.array(x.strip().split()), f.readlines())))for i in mask:i = np.array(i, dtype=np.float32)[1:].reshape((-1, 2))i[:, 0] *= wi[:, 1] *= hlabel = cv2.fillPoly(label, [np.array(i, dtype=np.int32)], color=255)image = cv2.bitwise_and(image, image, mask=label)cv2.imshow('Pic', image)cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

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

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

相关文章

iOS 设置下载部分文件,如何获取完整文件的大小

在视频的需求中,遇到这样一个需求,播放一视频的时候,要预下载 后面10条视频,但是只下载后面十条视频的前面1M 实现方法 1 创建请求时设置cacheLength resource [[IdiotResource alloc] init];resource.requestURL task.request…

不同路径 II【动态规划】

不同路径 II 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那么从左上…

深入解析即时通讯App开发中的关键技术

即时通讯App开发在现代社交和通信领域中扮演着重要的角色。随着移动设备的普及和网络的高速发展,人们对即时通讯工具的需求不断增加。本篇文章将深入探讨即时通讯App开发中的关键技术,帮助读者了解该领域的最新动态和技术趋势。 基础架构和通信协议 现…

阻塞/非阻塞、同步/异步(网络IO)

1.阻塞/非阻塞、同步/异步(网络IO) 【思考】典型的一次 IO 的两个阶段是什么? 数据就绪 和 数据读写 数据就绪 :根据系统 IO 操作的就绪状态 阻塞 非阻塞 数据读写 :根据应用程序和内核的交互方式 同步 异步 陈硕:在处理 IO …

ISP——3A算法

目录 前沿一. 自动曝光AE1.1. 自动曝光1.2. 18%灰1.3. 测光区域1.4. 摄影曝光加法系统1.5. AE算法1.5.1. 考虑事项1.5.2. AE实现过程 1.6. AE算法 二. 自动对焦AF2.1. 什么是自动对焦2.2. 图像清晰度评价方法2.2.1. Brenner 梯度函数2.2.2. Tenengrad 梯度函数2.2.3. Laplacian…

1.12 进程注入ShellCode套接字

在笔者前几篇文章中我们一直在探讨如何利用Metasploit这个渗透工具生成ShellCode以及如何将ShellCode注入到特定进程内,本章我们将自己实现一个正向ShellCodeShell,当进程被注入后,则我们可以通过利用NC等工具连接到被注入进程内,…

【vue】this.$nextTick解决this.$refs undefined的问题

说明 1、发邮件页面分成两个部分:模态框页面(头部和底部)和form页面(操作按钮) 2、点击回复按钮,要将发件人信息带到模态框页面,给定默认值且禁止收件人下拉选择(多个邮箱&#xff…

Windows Update Blocker,windows系统关闭自动更新工具

今天打开电脑发现系统又自动更新了 这一天天更新真的太烦了 然后我从网上找到一个工具 可以自由开启和关闭系统自动更新 这里分享一下网址:https://www.filehorse.com/download-windows-update-blocker/ 若网址失效,蓝奏云盘链接 https://wwgw.lanzouc.c…

归并排序的详解!

本文旨在讲解归并排序的实现(递归及非递归)搬好小板凳,干货来了! 前序: 在介绍归并排序之前,需要给大家介绍的是什么是归并,归并操作,也叫归并算法,指的是将两个顺序序列…

lv3 嵌入式开发-3 linux shell命令(文件搜索、文件处理、压缩)

目录 1 查看文件相关命令 1.1 常用命令 1.2 硬链接和软链接 2 文件搜索相关命令 2.1 查找文件命令 2.2 查找文件内容命令 2.3 其他相关命令 3 文件处理相关命令 3.1 cut 3.2 sed 过滤 3.3 awk 匹配 4 解压缩相关命令 4.1 解压缩文件的意义 4.2 解压缩相关命令 1 …

大学物理 之 安培环路定理

文章目录 前言什么是安培环路定理安培环路定理有什么作用 深入了解深入学习 前言 什么是安培环路定理 安培环路定理的物理意义在于描述了电流和磁场之间的相互作用,以及如何在一个封闭的回路中分析这种相互作用。 简单的来说 , 用环路定理来解决在磁场中B对任意封…

[管理与领导-65]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 乌卡时代(VUCA )

前言: 大多数IT人,很勤奋,但都没有职业规划,被工作驱动着前行,然而,作为管理者,你就不能没有职业规划思维,因为你代表一个团队,你的思维决定了一个团队的思维。本文探讨…

redis实战-实现优惠券秒杀解决超卖问题

全局唯一ID 唯一ID的必要性 每个店铺都可以发布优惠券: 当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题: id的规律性太明显,容易被用户根据id的间隔来猜测…

如何实现的手机实景自动直播,都有哪些功能呢?

手机实景自动直播最近真的太火了,全程只需要一部手机,就能完成24小时直播带货,不需要真人出镜,不需要场地,不需要搭建直播间,只需要一部手机就可以了。真人语音讲解,真人智能回复,实…

C#-单例模式

文章目录 单例模式的概述为什么会有单例模式如何创建单例模式1、首先要保证,该对象 有且仅有一个2、其次,需要让外部能够获取到这个对象 示例通过 属性 获取单例 单例模式的概述 总结来说: 单例 就是只有 一个实例对象。 模式 说的是设计模式…

《Go 语言第一课》课程学习笔记(十二)

函数 Go 函数与函数声明 在 Go 语言中,函数是唯一一种基于特定输入,实现特定任务并可返回任务执行结果的代码块(Go 语言中的方法本质上也是函数)。在 Go 中,我们定义一个函数的最常用方式就是使用函数声明。 第一部…

Mybatis学习|注解开发、lombok

1.使用注解开发 无需再编写相应的Mapper.xml文件,直接将sql用注解的形式写在Mapper接口的对应方法上即可。 然后因为没有xml文件,所以要在mybatis-config.xml核心配置文件中注册这个Mapper接口,而不用去注册之前的Mapper.xml,这里其实如果用…

QT listWidget 中实现元素的自由拖拽

QListWIdget中拖拽元素移动 setMovement(QListView::Movement::Free);setDragEnabled(true); setDragDropMode(DragDropMode::DragDrop); setDefaultDropAction(Qt::DropAction::MoveAction);

nginx-反向代理缓存

反向代理缓存相当于自动化动静分离。 将上游服务器的资源缓存到nginx本地,当下次再有相同的资源请求时,直接讲nginx缓存的资源返回给客户端。 本地缓存资源有一个过期时间,当超过过期时间,则重新向上游服务器重新请求获取资源。…

SIEM(安全信息和事件管理)解决方案

什么是SIEM 安全信息和事件管理(SIEM)是一种可帮助组织在安全威胁危害到业务运营之前检测、分析和响应安全威胁的解决方案,将安全信息管理 (SIM) 和安全事件管理 (SEM) 结合到一个安全管理系统中。SIEM 技术从广泛来源收集事件日志数据&…