制作数据集—labelImg和labelme

labelImg

首先安装labelImg
在Ancconda环境中pip install labelImg即可
然后直接在conda环境中运行labelImg即可打开软件、
软件操作非常简单,选择你要打开的文件夹(无标记的数据放这里)
然后选择要保存的路径
在下面创建一个标注框。
制作数据集---labelImg和labelme
创建标注框
自己创建一个类名,后面会自动显示
制作数据集---labelImg和labelme
标好了点击save保存
如果需要大量标注数据,使用快捷键非常方便。
按W就可以创建一个新的框,A是往前一张图,D是往后一张图。Ctrl+s是保存。

yolov5

以yolov为例(这里我用的是yolov5),为其标注VOC格式的数据集。
我们创建了几个文件夹
制作数据集---labelImg和labelme
要标注的图像放到images里面
标注保存的xml文件放在Annotations里面
制作数据集---labelImg和labelme
所有图片标注好了之后,把images下的图片,全部复制到ImageSets下
在yolo源码下创建文件夹myVOCdata
然后把这几个文件夹放在myVOCdata下面
然后在yolo源码下创建两个.py文件。make_txt.py和voc_label.py
make_txt.py代码如下: 注意看路径是否对应,如有改动,请相应改变

import os
import random
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'myVOCdata/Annotations'
txtsavepath = 'myVOCdata/ImageSets'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('myVOCdata/ImageSets/trainval.txt', 'w')
ftest = open('myVOCdata/ImageSets/test.txt', 'w')
ftrain = open('myVOCdata/ImageSets/train.txt', 'w')
fval = open('myVOCdata/ImageSets/val.txt', 'w')
for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

voc_label.py
代码如下: 注意看路径是否对应,如有变化请相应更改
注意更改此文件中的Classes!

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets = ['train', 'test','val']
classes = ['air blower', 'engineering room', 'hydroextractor1', 'hydroextractor2', 'With alkali tank', 'aquamanile', 'sand removing machine', 'cycle tank', 'filter', 'riddler', 'sit duty room']
def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)
def convert_annotation(image_id):
    in_file = open('myVOCdata/Annotations/%s.xml' % (image_id))
    out_file = open('myVOCdata/labels/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
print(wd)
for image_set in sets:
    if not os.path.exists('myVOCdata/labels/'):
        os.makedirs('myVOCdata/labels/')
    image_ids = open('myVOCdata/ImageSets/%s.txt' % (image_set)).read().strip().split()
    list_file = open('myVOCdata/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write('myVOCdata/images/%s.jpg\n' % (image_id))
        print(image_id)
        convert_annotation(image_id)
    list_file.close()

这两个.py文件位于yolo源码下面,与myVOCdata文件夹同级!
然后,在yolo源码下面data文件夹下,有一个voc.yaml,把这个文件复制到myVOCdata下
修改此文件中的路径和类别

train: myVOCdata/images/  # 16551 images
val: myVOCdata/images/ # 4952 images

# number of classes
nc: 5

# class names
names: [ 'Person','Blj','Zdb','piller','HL' ]

然后找到yolo的train.py文件,找到main,注意下面这几行

parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='model.ya ml path')
    parser.add_argument('--data', type=str, default='myVOCdata/VOC.yaml', help='data.yaml path')

如果你用的是yolov5s.yaml,那么你要去models文件夹下,找到yolov5s.yaml文件,把里面的nc: 5改成你的类别数
然后把第三行数据路径那里改成你的路径myVOCdata/VOC.yaml
然后先运行make_txt.py,ImageSets下面会生成一些txt文件
再运行voc_label.py,
然后就可以开始训练了。运行train.py开始训练。

labelme

该数据集用于标记语义分割。
效果类似这样

安装方法是一样的
在Ancconda环境中pip install labelme即可
然后直接在conda环境中运行labelme即可打开软件
使用方法非常简单,一目了然
打开文件,标注,保存save
制作数据集---labelImg和labelme
标注时,必须首尾相连
制作数据集---labelImg和labelme
圈起来后给他一个班级名称,不同班级会有不同的颜色
将显示在右侧,这是红色的
制作数据集---labelImg和labelme
标注好了之后保存下来的是json文件
制作数据集---labelImg和labelme
这个文件有多种打开方式。下面以PFNet训练为例

PFNet训练

标注好的jpg文件和json文件
还需要用一个程序json_to_dataset.py
代码如下: 也很容易理解,改路径即可

import base64
import json
import os
import os.path as osp

import numpy as np
import PIL.Image
from labelme import utils

if __name__ == '__main__':
    jpgs_path   = r"E:\video\pic\test_jpg"  # 标注的图像路径
    pngs_path   = r"E:\video\pic\test_json" # json文件存放路径
    classes     = ["_background_", "vibrating tube"] # 标注的类别  第一个是背景不用改
    # classes = ["_background_", "per"]
    # classes     = ["_background_","cat","dog"]
    
    count = os.listdir(pngs_path)
    for i in range(0, len(count)):
        path = os.path.join(pngs_path, count[i])

        if os.path.isfile(path) and path.endswith('json'):
            data = json.load(open(path))
            
            if data['imageData']:
                imageData = data['imageData']
            else:
                imagePath = os.path.join(os.path.dirname(path), data['imagePath'])
                with open(imagePath, 'rb') as f:
                    imageData = f.read()
                    imageData = base64.b64encode(imageData).decode('utf-8')

            img = utils.img_b64_to_arr(imageData)
            label_name_to_value = {'_background_': 0}
            for shape in data['shapes']:
                label_name = shape['label']
                if label_name in label_name_to_value:
                    label_value = label_name_to_value[label_name]
                else:
                    label_value = len(label_name_to_value)
                    label_name_to_value[label_name] = label_value
            
            # label_values must be dense
            label_values, label_names = [], []
            for ln, lv in sorted(label_name_to_value.items(), key=lambda x: x[1]):
                label_values.append(lv)
                label_names.append(ln)
            assert label_values == list(range(len(label_values)))
            
            lbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value)[0]
            
                
            # PIL.Image.fromarray(img).save(osp.join(jpgs_path, count[i].split(".")[0]+'.jpg'))

            new = np.zeros([np.shape(img)[0],np.shape(img)[1]])
            for name in label_names:
                index_json = label_names.index(name)
                index_all = classes.index(name)
                new = new + index_all*(np.array(lbl) == index_json)

            # utils.lblsave(osp.join(pngs_path, count[i].split(".")[0]+'.png'), new)
            # print('Saved ' + count[i].split(".")[0] + '.jpg and ' + count[i].split(".")[0] + '.png')
            utils.lblsave(osp.join(pngs_path, count[i] + '.png'), new)
            print('Saved ' + count[i] + '.jpg and ' + count[i] + '.png')

用这个程序处理json文件,处理完了之后会在json的文件夹下生成这样的图像
制作数据集---labelImg和labelme
这是标记的对象
制作数据集---labelImg和labelme
把原图和最后生成的这个.json.png图像名字对应好
你可以拿它来训练。

版权声明:本文为博主1900_原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/holly_Z_P_F/article/details/123318836

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2022年3月7日 下午5:17
下一篇 2022年3月7日 下午5:43

相关推荐