【旷世CrowdHuman数据集分析、使用】

零、数据下载

旷世CrowdHuman数据集官网
旷世CrowdHuman数据集官网

数据下载地址
数据集下载网页

一、划分数据集

这里只讲解验证数据集的解析方式,训练集同理。

  • 将下载好的图像文件解压
    解压文件
  • 提取出解压后的Images文件夹复制到自己创建的test文件夹中,有4370张图片(训练数据集分为01、02和03三个压缩包,分别提取出其中的images文件夹,合并成一个。三个压缩包每个5000张图片,合成之后的Images文件夹中15000张图片)
    解压后转移到test文件夹下
  • 按照上述操作之后形成如下图所示的目录结构
    图像文件和标签文件的位置

二、分析数据标注文件

第一次使用旷世提供的CrowdHuman dataset对应的annotation_train.odgt标注文件时,容易懵逼,无从下手。让我们逐项分析这些数据:

annotation_val.odgt
上图是在vscode中打开的annotation_val.odgt文件,每一行代表一张图片的标注信息。下面分析一下每张图片的标注信息。

  • "ID": "273271,c9db000d5146c15"

    • 表示该图像的唯一标识符,与对应的图片文件同名
  • "gtboxes"
    这是一个列表,包含了该图像中所有检测到的人体对象的信息。列表中每个对象都是一个字典,描述了一个人体实例,包含以下键值对:

    • "fbox": [72, 202, 163, 503]
      • 这是该人体实例的全身边界框坐标,格式为 [x, y, w, h]。
    • "tag": "person"
      • 表明这是一个人体实例。
    • "hbox": [171, 208, 62, 83]
      • 这是该人体实例的头部边界框坐标。
    • "extra": {"box_id": 0, "occ": 0}
      • box_id是该实例的唯一标识符,occ代表是否被遮挡,0表示未遮挡。
    • "vbox": [72, 202, 163, 398]
      • 这是该人体实例的可见部分边界框坐标。
    • "head_attr": {"ignore": 0, "occ": 0, "unsure": 0}
      • 这描述了与头部有关的属性,ignoreoccunsure分别表示是否忽略、是否遮挡和是否不确定。全为0表示正常情况。

三、解析annotation.odgt文件

import json
import os
import cv2
from pathlib import Path

def image_shape(ID: str, images_dir: Path) ->tuple:
    jpg_path = images_dir / ('%s.jpg' % ID)
    assert jpg_path.is_file(), f"{jpg_path} not found"
    img = cv2.imread(jpg_path.as_posix())
    return img.shape

def Normalized(size_list: list, original_shape: tuple) -> str:
    x, y, w, h = size_list
    ori_w, ori_h = original_shape[:2]
    cx = (x + w / 2) / w
    cy = (y + h / 2) / h
    w /= ori_w
    h /= ori_h
    return f"{cx:.6f} {cy:.6f} {w:.6f} {h:.6f}\n"

def process(annotation_filename: str, output_dir: Path, images_dir: Path, classes_list: list):
    assert output_dir is not None
    output_dir.mkdir(exist_ok=True)
    with open(annotation_filename, 'r') as fanno:
        for raw_anno in fanno.readlines():
            anno = json.loads(raw_anno)
            ID = anno['ID']  # e.g. '273271,c9db000d5146c15'
            print('Processing ID: %s' % ID)

            original_shape = image_shape(ID, images_dir)  # 获取原始图像size,方便后续归一化 (600, 800, 3)

            txt_path = output_dir / ('%s.txt' % ID)  # 标注文件生成地址

            with open(txt_path.as_posix(), 'w') as ftxt:
                for obj in anno['gtboxes']:
                    if obj['tag'] != 'person':
                        continue

                    for i, cls in enumerate(classes_list):
                        if cls in obj.keys(): 
                            assert len(obj[cls]) == 4, f"{cls} error '{ID}.txt' "
                            line = f"{i} " + Normalized(obj[cls], original_shape)
                            ftxt.write(line)


if __name__ == "__main__":
    process(r"F:\crowdhuman\annotation_val.odgt", Path("./test/labels"), Path("./test/Images"), ['fbox', 'hbox'])
    process(r"F:\crowdhuman\annotation_train.odgt", Path("./train/labels"), Path("./train/Images"), ['fbox', 'hbox'])

  1. image_shape 函数根据给定的图像 ID 和图像目录路径,读取对应的图像文件,并返回图像的形状(高度、宽度和通道数)。
    Normalized 函数将边界框坐标从像素值转换为归一化的相对值,以适应 YOLO 格式的要求。它接受两个参数:一个包含边界框坐标 [x, y, w, h] 的列表和原始图像的形状。计算出边界框中心点的相对坐标 (cx, cy) ,以及相对于图像宽度和高度的归一化边界框宽度和高度。最后,将这些值格式化为一个字符串,并返回。
  2. process 函数是主要的处理函数。它接受四个参数:
    • annotation_filename : CrowdHuman 数据集的标注文件路径。
    • output_dir : 用于存储生成的 YOLO 格式标注文件的输出目录路径。
    • images_dir : 包含图像文件的目录路径。
    • classes_list : 一个列表,包含需要处理的边界框类型,如 ['fbox', 'hbox']
      该函数首先创建输出目录(如果不存在)。然后,它逐行读取标注文件中的 JSON 数据。对于每个 JSON 对象,它提取图像 ID,获取原始图像的形状,并构造输出的 YOLO 格式标注文件路径。
      接下来,它遍历每个目标对象的边界框信息。如果该对象是 'mask' 类型,则跳过。否则,它断言该对象是 'person' 类型。然后,对于每个指定的边界框类型( classes_list 中的元素),如果该对象包含该类型的边界框坐标,就将其转换为 YOLO 格式的标注行,并写入输出文件。
  3. 最后,在主程序中,调用 process 函数处理验证集和训练集的标注文件,并将生成的 YOLO 格式标注文件存储在 ./test/labels./train/labels 目录中。处理时,只考虑了 'fbox''hbox'两种边界框类型。

四、结语

后续可以根据自己的需求对代码部分进行修改。有错误的地方欢迎指正。

  • 21
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值