WiderPerson提取指定类别转YOLO格式

WiderPerson介绍参考这位作者【数据集处理】WiderPerson介绍以及转YOLO格式(图片教程及代码----超详细)_widerperson数据集-CSDN博客下载后的文件样式

标注信息Annotations


Annotations中文件名类似:000041.jpg.txt,共9000条信息,其中训练8000条,验证1000条

第一行是该张图片中标注数量
第二行【所属类别 xmin ymin xmax ymax】

标签可视化代码

注意:在部分人的电脑上00040文件是问题文件,打开是乱码,需要将annotations、images、train.txt中对应的删除掉再运行代码,但我这里没有乱码 ,所以直接转

import os
import cv2

if __name__ == '__main__':
    path = 'D:\\WiderPerson\\train.txt'   
    with open(path, 'r') as f:
        img_ids = [x for x in f.read().splitlines()]

    for img_id in img_ids:  # '000040'
        img_path = 'D:\\WiderPerson\\Images\\' + img_id + '.jpg'
        img = cv2.imread(img_path)

        im_h = img.shape[0]
        im_w = img.shape[1]
        print(img_path)
        label_path = img_path.replace('Images','Annotations') + '.txt'
        print(label_path)
        with open(label_path) as file:
            line = file.readline()
            count = int(line.split('\n')[0])  # 里面行人个数
            line = file.readline()
            while line:
                cls = int(line.split(' ')[0])
                print(cls)
                # < class_label =1: pedestrians > 行人
                # < class_label =2: riders >      骑车的
                # < class_label =3: partially-visible persons > 遮挡的部分行人
                # < class_label =4: ignore regions > 一些假人,比如图画上的人
                # < class_label =5: crowd > 拥挤人群,直接大框覆盖了
                if cls == 1  or cls == 3:
                    xmin = float(line.split(' ')[1])
                    ymin = float(line.split(' ')[2])
                    xmax = float(line.split(' ')[3])
                    ymax = float(line.split(' ')[4].split('\n')[0])
                    img = cv2.rectangle(img, (int(xmin), int(ymin)), (int(xmax), int(ymax)), (0, 255, 0), 2)
                line = file.readline()
        cv2.imshow('result', img)
        cv2.waitKey(0)


转格式以及选取类别

import os
from PIL import Image
import shutil


# coding=utf-8
def check_charset(file_path):
    import chardet
    with open(file_path, "rb") as f:
        data = f.read(4)
        charset = chardet.detect(data)['encoding']
    return charset


def convert(size, box0, box1, box2, box3):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box0 + box2) / 2 * dw
    y = (box1 + box3) / 2 * dh
    w = (box2 - box0) * dw
    h = (box3 - box1) * dh
    return (x, y, w, h)


if __name__ == '__main__':

    outpath_txt = 'D:\\WiderPerson\\WiderPerson\\label\\val'
    # 注意:这里F:\\WiderPerson是你存储文件侧地方,可以替换,后面的不要动
    outpath_jpg = 'D:\\WiderPerson\\WiderPerson\\images\\val'
    # 注意:这里F:\\WiderPerson是你存储文件侧地方,可以替换,后面的不要动
    os.makedirs(outpath_txt)
    os.makedirs(outpath_jpg)

    path = 'D:\\WiderPerson\\val.txt'
    with open(path, 'r') as f:
        img_ids = [x for x in f.read().splitlines()]

    for img_id in img_ids:  # '000040'
        img_path = 'D:\\WiderPerson\\Images\\' + img_id + '.jpg'

        with Image.open(img_path) as Img:
            img_size = Img.size

        ans = ''

        label_path = img_path.replace('Images', 'Annotations') + '.txt'

        outpath = outpath_txt + "\\" + img_id + '.txt'

        with open(label_path, encoding=check_charset(label_path)) as file:
            line = file.readline()
            count = int(line.split('\n')[0])  # 里面行人个数
            line = file.readline()
            while line:
                cls = int(line.split(' ')[0])
                if cls == 1 or cls == 2 or cls == 3 or cls == 4 or cls == 5:
                    # if cls == 1  or cls == 3:如果是多类别可以在后面加or cls == 3
                    xmin = float(line.split(' ')[1])
                    ymin = float(line.split(' ')[2])
                    xmax = float(line.split(' ')[3])
                    ymax = float(line.split(' ')[4].split('\n')[0])
                    print(img_size[0], img_size[1], xmin, ymin, xmax, ymax)
                    bb = convert(img_size, xmin, ymin, xmax, ymax)
                    # ans = ans + '1' + ' ' + ' '.join(str(a) for a in bb) + '\n'
                    ans = ans + str(cls) + ' ' + ' '.join(str(a) for a in bb) + '\n'# 如果你选用的是多类别,建议用下面这行代码,直接使用cls类别号去重新构建标注文件,如果你只选择一类,可用上面的注释代码ans + '*',我这里是选择了多类
                line = file.readline()
        with open(outpath, 'w') as outfile:
            outfile.write(ans)
        # 想保留原文件用copy
        # shutil.copy(img_path, outpath_o + '\\' + img_id + '.jpg')
        # 直接移动用这个
        shutil.move(img_path, outpath_jpg + '\\' + img_id + '.jpg')

如果你选用的是多类别,建议用65行代码,直接使用cls类别号去重新构建标注文件,如果你只选择1类(类别选择在56行代码),可用64行被注释代码ans + '*',*指代你选择的类别,我这里是选择了多类

运行val完毕后,运行后将代码27行、29行、34行中val替换成train 再运行一遍!

运行完毕后,打开D:\WiderPerson\images文件夹 里面剩余4382张图片,都是测试图片,可以直接重命名为test然后移动到D:\WiderPerson\WiderPerson\images中和train和val文件夹并列

类别转换

import os

# 路径
otxt_path = "D:\\WiderPerson\\WiderPerson\\label\\val"  
ntxt_path = "D:\\WiderPerson\\WiderPerson\\labels\\val"
os.makedirs(ntxt_path) 

filer = []
for root, dirs, files in os.walk(otxt_path):
    for i in files:
        otxt = os.path.join(otxt_path, i)
        ntxt = os.path.join(ntxt_path, i)
        f = open(otxt, 'r', encoding='utf-8')
        for line in f.readlines():
            if line == '\n':
                continue
            cls = line.split(" ")
            # cls = '%s'%(int(cls[0])-1) + " " + cls[1]+ " " + cls[2]+ " " + cls[3]+ " " + cls[4]
            cls = '0' + " " + cls[1]+ " " + cls[2]+ " " + cls[3]+ " " + cls[4]
            filer.append(cls)
        with open(ntxt,"a") as f:
            for i in filer:
                f.write(i)
        filer = []

注意代码注释掉的第20行:

cls = '%s'%(int(cls[0])-1) + " " + cls[1]+ " " + cls[2]+ " " + cls[3]+ " " + cls[4]

如果你的类别留的是1、2、3、4,这种多类别,此行代码是将其变为 0、1、2、3
主要针对YOLO算法的标签要从0开始的这个规定

而如果你需要将1、2、3、4类别都当做是一类
那么不用解开注释,这段代码也相当于是归类处理了,将val换成train再来一遍

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值