YOLO V8半自动标注工具设计

embedded/2024/10/19 12:17:27/

前提:
对于某些边界不明确的小目标,要是目标由比较多的话,标注起来就会非常麻烦。
如何利用已有训练模型,生成框,进行预标注。再通过调节预标注框的方式,提高标注的效率。

1 通过预先训练的模型生成yolo 格式的框

python">
image_absolute_path = "yyy_test/img/L206_20240516101319_2_20240516101319_N49_2.jpg"
# Load the YOLOv8 model#
model = YOLO('./runs/detect/train4080/26/last.pt')  # 4080
# Open the video file
image = cv.imread(image_absolute_path, 1)
results = model.predict(image_absolute_path, imgsz=640, show=True)
shape = image.shape
# float_rect[0] *= shape[1]
# float_rect[1] *= shape[0]
# float_rect[2] *= shape[1]
# float_rect[3] *= shape[0]
filename = image_absolute_path.replace('jpg', 'txt')  # 将path里的json替换成txt,生成txt里相对应的文件路径
w = shape[1]
h = shape[0]
fh = open(filename, 'w', encoding='utf-8')
all_line = ''
results[0].plot()
for result in results:for r in result.boxes.data.tolist():x1, y1, x2, y2, score, class_id = rx1, x2 = x1 / w, x2 / wy1, y2 = y1 / h, y2 / hcx = (x1 + x2) / 2cy = (y1 + y2) / 2wi = abs(x2 - x1)hi = abs(y2 - y1)line = "%s %.4f %.4f %.4f %.4f\n" % (class_id, cx, cy, wi, hi)  # 生成txt文件里每行的内容all_line += line
fh.write(all_line)

yolo .txt 格式的框
在这里插入图片描述

2 将yolo 格式 转换为labelme 格式

python">import cv2
import os
import json
import shutil
import numpy as np
from pathlib import Pathdic = {0: 'NVshaoxi', 1: "Nqiaoqi", 2: 'Nqiaojie',3: 'N_pianyi',4: "N_yiwu" ,\5: 'NVshaoxi', 6: "NVqiaoqi", 7: 'NVqiaojie',8: 'NV_pianyi',9: "NV_yiwu"}
def xyxy2labelme(labels, w, h, image_path, save_dir='res/'):save_dir = str(Path(save_dir)) + '/'if not os.path.exists(save_dir):os.makedirs(save_dir)label_dict = {}label_dict['version'] = '5.0.1'label_dict['flags'] = {}label_dict['imageData'] = Nonelabel_dict['imagePath'] = image_pathlabel_dict['imageHeight'] = hlabel_dict['imageWidth'] = wlabel_dict['shapes'] = []for l in labels:tmp = {}tmp['label'] = dic[int(l[0])]tmp['points'] = [[l[1], l[2]], [l[3], l[4]]]tmp['group_id'] = Nonetmp['shape_type'] = 'rectangle'tmp['flags'] = {}label_dict['shapes'].append(tmp)fn = save_dir + image_path.rsplit('.', 1)[0] + '.json'with open(fn, 'w') as f:json.dump(label_dict, f)def yolo2labelme(yolo_image_dir, yolo_label_dir, save_dir='res/'):yolo_image_dir = str(Path(yolo_image_dir)) + '/'yolo_label_dir = str(Path(yolo_label_dir)) + '/'save_dir = str(Path(save_dir)) + '/'image_files = os.listdir(yolo_image_dir)for iimgf, imgf in enumerate(image_files):print(iimgf + 1, '/', len(image_files), imgf)fn = imgf.rsplit('.', 1)[0]shutil.copy(yolo_image_dir + imgf, save_dir + imgf)image = cv2.imread(yolo_image_dir + imgf)h, w = image.shape[:2]if not os.path.exists(yolo_label_dir + fn + '.txt'):continuelabels = np.loadtxt(yolo_label_dir + fn + '.txt').reshape(-1, 5)if len(labels) < 1:continuelabels[:, 1::2] = w * labels[:, 1::2]labels[:, 2::2] = h * labels[:, 2::2]labels_xyxy = np.zeros(labels.shape)labels_xyxy[:, 0] = np.clip(labels[:, 0], 0, 20)labels_xyxy[:, 1] = np.clip(labels[:, 1] - labels[:, 3] / 2, 0, w)labels_xyxy[:, 2] = np.clip(labels[:, 2] - labels[:, 4] / 2, 0, h)labels_xyxy[:, 3] = np.clip(labels[:, 1] + labels[:, 3] / 2, 0, w)labels_xyxy[:, 4] = np.clip(labels[:, 2] + labels[:, 4] / 2, 0, h)xyxy2labelme(labels_xyxy, w, h, imgf, save_dir)print('Completed!')if __name__ == '__main__':yolo_image_dir = 'E:/pythonCode/pythonProject1/yyy_test/img/'yolo_label_dir = 'E:/pythonCode/pythonProject1/yyy_test/txt/'save_dir ='E:/pythonCode/pythonProject1/res/'yolo2labelme(yolo_image_dir, yolo_label_dir, save_dir)

labelme 的 .json格式
在这里插入图片描述

3 用labelme 微调标注框

将刚才生成的与图片名称相同的后缀为.json 的文件和图片放在同一个目录下,然后用labelme 打开该dir。
在这里插入图片描述

4 再将labelme 格式的数据变为yolo 格式,加入训练

python">import json
import cv2
import numpy as np
import os
def json2yolo(path):# dic={'N_shaoxi':'0',   'N_qiaoqi':'1',   'N_qiaojie':'2',   'N_pianyi':'3',   'N_yiwu': '4', \#      'NV_shaoxi': '5', 'NV_qiaoqi': '6', 'NV_qiaojie': '7', 'NV_pianyi': '8', 'NV_yiwu': '9',\#      'R_shaoxi': '10',  'R_qiaoqi': '11',  'R_qiaojie': '12',  'R_pianyi': '13',  'R_yiwu': '14',\#      'XS_shaoxi': '15', "XS_qiaoqi": '16', 'XS_qiaojie': '17', 'XS_pianyi': '18', 'XS_yiwu': '19',#      '1': '0'}dic={'N_shaoxi':'0',   'N_qiaoqi':'1',   'N_qiaojie':'2',   'N_pianyi':'3',   'N_yiwu': '4', \'NV_shaoxi': '5', 'NV_qiaoqi': '6', 'NV_qiaojie': '7', 'NV_pianyi': '8', 'NV_yiwu': '9',\'R_shaoxi': '10',  'R_qiaoqi': '11',  'R_qiaojie': '12',  'R_pianyi': '13',  'R_yiwu': '14',\'XS_shaoxi': '15', "XS_qiaoqi": '16', 'XS_qiaojie': '17', 'XS_pianyi': '18', 'XS_yiwu': '19','XP_shaoxi': '15', "XP_qiaoqi": '16', 'XP_qiaojie': '17', 'XP_pianyi': '18', 'XP_yiwu': '19'}#dic = {'N_shaoxi': '0', 'N_shaoxi': '1','N_qiaojie': '2','N_pianyi':'3','N_yiwu:'4'}  # 类别字典if ".json" in path:data = json.load(open(path,encoding="utf-8"))#读取带有中文的文件w=data["imageWidth"]#获取jaon文件里图片的宽高h=data["imageHeight"]all_line=''for i in  data["shapes"]:#归一化坐标点。并得到cx,cy,w,h[[x1,y1],[x2,y2]]=i['points']x1,x2=x1/w,x2/wy1,y2=y1/h,y2/hcx=(x1+x2)/2cy=(y1+y2)/2wi=abs(x2-x1)hi=abs(y2-y1)#将数据组装成yolo格式line="%s %.4f %.4f %.4f %.4f\n"%(dic[i['label']],cx,cy,wi,hi)#生成txt文件里每行的内容all_line+=line# print(all_line)filename = path.replace('json','txt')#将path里的json替换成txt,生成txt里相对应的文件路径fh = open(filename,'w',encoding='utf-8')fh.write(all_line)fh.close()else:filename = path.replace('.jpg', '.txt')  # 将path里的json替换成txt,生成txt里相对应的文件路径fh = open(filename, 'w', encoding='utf-8')fh.close()path= "E:/919XP/" # /
path_list_sub = os.listdir(path)
print("path_list_sub", path_list_sub)
for path_sub in path_list_sub:json_path_list =os.listdir(path+path_sub)path_list2=[x for x in json_path_list]#获取所有json文件的路径# path_list2 = [x for x in json_path_list if ".json" in x]  # 获取所有json文件的路径print("len of path_list2 ",path_sub,len(path_list2))for p in path_list2:absolute_path= (path+path_sub+'/'+p)print("abs path",absolute_path)json2yolo(path+path_sub+'/'+p)

http://www.ppmy.cn/embedded/120016.html

相关文章

遥感影像-实例分割数据集:iSAID 从切图到YOLO格式数据集制作详细介绍

背景介绍 开源数据集isaid标注包含实例分割&#xff0c;但是原始影像太大&#xff0c;很吃显存&#xff0c;一般显卡无法用原始影像直接训练&#xff0c;所以需要对影像进行裁剪&#xff0c;并生成对应的标签&#xff0c;因为想用yolo系列跑模型&#xff0c;所以将标签需要转为…

详解Java之继承与多态

目录 继承 派生类和基类各部分执行顺序 protected 访问权限总结 final关键字 组合 多态 向上转型 向下转型 动态绑定 静态绑定 方法重载 方法重写 super关键字 super和this的对比 在构造方法中调用重写方法 继承 继承是为了解决多个类具有一些相同的属性和方…

网络安全入门

1. 简介 1.1. 概述 网络安全是一个复杂而重要的领域,它涉及保护网络系统的硬件、软件及其数据免受未经授权的访问、使用、泄露、中断、修改或破坏。网络安全是指通过采取必要措施,防范对网络的攻击、侵入、干扰、破坏和非法使用以及意外事故,使网络处于稳定可靠运行的状态,…

Java | Leetcode Java题解之第438题找到字符串中所有字母异位词

题目&#xff1a; 题解&#xff1a; class Solution {public List<Integer> findAnagrams(String s, String p) {int sLen s.length(), pLen p.length();if (sLen < pLen) {return new ArrayList<Integer>();}List<Integer> ans new ArrayList<Int…

Qt QIntValidator详解

一、介绍 QIntValidator是Qt框架中用于验证整数输入的验证器类。它可以限制用户输入的整数范围&#xff0c;确保输入的整数在指定的范围内。通过QIntValidator&#xff0c;可以轻松地实现整数输入的有效性和范围限制。 二、 常用方法 QIntValidator(QObject *parent Q_NULLPT…

Python 课程18-SQLAlchemy

前言 SQLAlchemy 是一个功能强大的 Python SQL 工具包和对象关系映射&#xff08;ORM&#xff09;库&#xff0c;它使得开发者能够通过 Python 代码与数据库进行交互&#xff0c;而不必编写 SQL 查询。SQLAlchemy 提供了对多种数据库的支持&#xff0c;包括 MySQL、PostgreSQL…

机器人顶刊IEEE T-RO发布无人机动态环境高效表征成果:基于粒子的动态环境连续占有地图

摘要&#xff1a;本研究有效提高了动态环境中障碍物建模的精度和效率。NOKOV度量动作捕捉系统助力评估动态占用地图在速度估计方面的性能。 近日&#xff0c;上海交通大学、荷兰代尔夫特理工研究团队在机器人顶刊IEEE T-RO上发表题为Continuous Occupancy Mapping in Dynamic …

【AI大模型-文心-思维树解读-仓颉精通之路-4】

提问&#xff1a;对于每个解决方案&#xff0c;加深思考过程。生成潜在场景、实施策略、任何必要的资源、如何克服障碍与风险以及意外结果和意外结果的处理 回答&#xff1a;如下 版本&#xff1a;文心大模型3.5 解决方案一&#xff1a;系统化自学方案 潜在场景&#xff1a; …