如何从voc数据集中提取出自己想要的类别,比如person,cat

80 阅读2分钟

由于要参加一个小比赛,需要使用darknet框架训练yolo模型,于是打算先找数据集,然后就看到了voc。可以从这个网站上找到很多开源的数据集,从这里下载一个darknet版本的voc:app.roboflow.com/

image.png 之后我上网搜到了这篇博客,写的很好:xugaoxiang.com/2021/11/26/… 这个博客里面的这个python代码,作用是根据voc中的图片中的标签,把需要的部分拿出来,可以修改为自己需要的类别,想要取出多种类别的也可以,让chatgpt给修改一下就好,很简单。我不懂python,但是大概逻辑可以看明白,我有chatgpt,为大家写一下注释:

import os
import shutil

# 统计最后符合条件的图片数量
counter = 0

# 创建两个目标文件夹,一个用于存放图片,一个用于存放标注
if not os.path.exists('images'):
    os.makedirs('images')
if not os.path.exists('labels'):
    os.makedirs('labels')

# 遍历指定文件夹中的所有文件
for file in os.listdir('train'):
    flag = False

    # 检查文件是否以'.txt'结尾,即标注文件
    if file.endswith('.txt'):
        f = open("train/{}".format(file), 'r')
        line = f.readline()

        # 原数据集中有些txt文件大小为0,内容为空,跳过这些文件
        if line == "":
            continue

        while line:
            # 去除每行中的第一列的值,即类别ID
            tmp = line.split(' ')[0]

            # 判断是否为人体目标,人体目标的ID14
            if tmp != "14":
                print('NOT person.')
                flag = True
                break

            line = f.readline()

        f.close()

        if not flag:
            counter += 1
            prefix = file[0: -3]
            # 拷贝符合条件的图片和对应的标注到目标文件夹
            shutil.copy2('train/{}jpg'.format(prefix), 'images')
            shutil.copy2('train/{}'.format(file), 'labels')

# 打印符合条件的图片数量
print('total number of images: {}'.format(counter))

接下来就把这个代码放到一个txt文件里,保存,后缀改成.py,把这个代码文件放到下载好的voc的数据集根目录里,右键在当前目录打开cmd,python ./代码文件名命令就可以运行了,弄好之后是这样子的:

image.png

imageslabels就是结果了,后面他写的很好:

那接下来就要去修改标注中的 class id 了, 在 VOC2012 中,人的 id 是14(从0开始), 考虑到新的数据集只有人这一类,所以 id 就是0, 那工作就变成要将 txt 文件中的第一列数据中的 14 改为 0

然后我们要修改txt文件中第一列数据,怎么改呢,使用vim比较方便,如果大家有更方便的办法可以评论一下。vim整列输入看这个博客就可以了,整列修改一下。然后这个数据集就处理完了。 对我个人而言,还要再做一点操作,我的数据集结构是这样的:

|-- test_dataset
|   |-- JPEGImages
|   |-- labels
|   `-- list
`-- training_dataset
    |-- JPEGImages
    |-- labels
    `-- list