YOLO V8半自动标注工具设计

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

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


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 = r
        x1, x2 = x1 / w, x2 / w
        y1, y2 = y1 / h, y2 / h
        cx = (x1 + x2) / 2
        cy = (y1 + y2) / 2
        wi = 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 格式

import cv2
import os
import json
import shutil
import numpy as np
from pathlib import Path

dic = {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'] = None
    label_dict['imagePath'] = image_path
    label_dict['imageHeight'] = h
    label_dict['imageWidth'] = w
    label_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'] = None
        tmp['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'):
            continue
        labels = np.loadtxt(yolo_label_dir + fn + '.txt').reshape(-1, 5)
        if len(labels) < 1:
            continue
        labels[:, 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 格式,加入训练

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/w
            y1,y2=y1/h,y2/h
            cx=(x1+x2)/2
            cy=(y1+y2)/2
            wi=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)
YOLO(You Only Look Once)是一种流行的目标检测算法,其特点是能够快速而准确地检测图像中的多个物体。为了提高YOLO算法的效率,开发者们还设计了一种自动标注工具,能够帮助用户自动标注训练数据集。 YOLO自动标注工具的原理是利用计算机视觉技术,通过图像处理算法自动检测和定位感兴趣的物体,并为其生成标注框。该工具可以根据用户需求,对图像中的物体进行分类和定位,生成标注结果。 YOLO自动标注工具具有以下优点: 1. 自动化:相比于传统的手动标注方法,YOLO自动标注工具能够快速、高效地完成标注任务,减少了人工操作的时间和精力。 2. 精度高:该工具利用先进的目标检测算法,能够准确地检测并定位图像中的物体,生成准确的标注结果。 3. 可扩展性:YOLO自动标注工具可以灵活地根据用户需求进行定制化设置,满足不同任务的标注需求。 4. 多标签支持:该工具支持对图像中多个物体进行标注,可以识别并标注出不同类别的物体。 尽管YOLO自动标注工具具有许多优点,但也存在一些潜在的问题。例如,在复杂场景下,该工具可能会出现一定的识别误差;此外,它还依赖于训练数据集的质量和数量,因此需要一定的数据准备工作。 总之,YOLO自动标注工具在目标检测任务中具有重要的应用价值,能够大大提高标注效率和准确性。然而,对于特定的应用场景和数据集,用户需要权衡其优势和限制,并进行适当的调整和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值