使用新版FLIR (FLIR_ADAS_v2) 数据集创建yolo格式数据集(目标检测)

FLIR在2022.1.19发布了新版的FLIR_ADAS_v2,有着更多的类别和数量更丰富的图像。数据集同步注释热图像和无注释RGB图像供参考。本文章主要介绍如何使用FLIR_ADAS_v2中的rgb图像和thermal图像来制作yolo格式数据集。

1.官方数据集下载:FLIR_ADAS_v2数据集下载

2. 将单个json文件转换为多个xml文件

需要注意的是代码里面的文件位置是当时把官方文件下载的 COCO 数据集所在目录,读取的json 文件所在位置是看需要用的是rgb图像或者thermal图像的train或者val。

另外生成的xml文件存放位置一定要和json文件相对应,也就是说新建的文件夹里一定包含data文件夹,只这样才能生成xml文件,不然会报错"filenotfounderror: [errno 2] no such file or directory: '..."。即保存文件里面的data文件夹一定要新建好,再运行代码。

python代码如下:

复制代码
# translate coco_json to xml
import os
import time
import json
import pandas as pd
from tqdm import tqdm
from pycocotools.coco import COCO


def trans_id(category_id):
    names = []
    namesid = []
    for i in range(0, len(cats)):
        names.append(cats[i]['name'])
        namesid.append(cats[i]['id'])
        # print('id:{1}\t {0}'.format(names[i], namesid[i]))
    index = namesid.index(category_id)
    return index


root = r'G:/红外数据集-FLIR2/FLIR_ADAS_v2/images_thermal_train'  # 你下载的 COCO 数据集所在目录
dataType = '2017'
anno = r'G:/红外数据集-FLIR2/FLIR_ADAS_v2/images_thermal_train/coco.json'  # annotation json 文件所在位置
xml_dir = r'G:/红外数据集-FLIR2/FLIR2_yolo_xml/images_thermal_train'  # 导出的xml文件所在的位置

coco = COCO(anno)  # 读文件
cats = coco.loadCats(coco.getCatIds())  # 这里loadCats就是coco提供的接口,获取类别

# Create anno dir
dttm = time.strftime("%Y%m%d%H%M%S", time.localtime())
# if os.path.exists(xml_dir):
#     os.rename(xml_dir, xml_dir + dttm)
# os.mkdir(xml_dir)

with open(anno, 'r') as load_f:
    f = json.load(load_f)

imgs = f['images']  # json文件的img_id和图片对应关系 imgs列表表示多少张图

cat = f['categories']
df_cate = pd.DataFrame(f['categories'])  # json中的类别
df_cate_sort = df_cate.sort_values(["id"], ascending=True)  # 按照类别id排序
categories = list(df_cate_sort['name'])  # 获取所有类别名称
print('categories = ', categories)
df_anno = pd.DataFrame(f['annotations'])  # json中的annotation

for i in tqdm(range(len(imgs))):  # 大循环是images所有图片
    xml_content = []
    file_name = imgs[i]['file_name']  # 通过img_id找到图片的信息
    height = imgs[i]['height']
    img_id = imgs[i]['id']
    width = imgs[i]['width']

    # xml文件添加属性
    xml_content.append("<annotation>")
    xml_content.append("	<folder>VOC2007</folder>")
    xml_content.append("	<filename>" + file_name.split('/')[1].split('.')[0] + '.jpg' + "</filename>")
    xml_content.append("	<size>")
    xml_content.append("		<width>" + str(width) + "</width>")
    xml_content.append("		<height>" + str(height) + "</height>")
    xml_content.append("	</size>")
    xml_content.append("	<segmented>0</segmented>")

    # 通过img_id找到annotations
    annos = df_anno[df_anno["image_id"].isin([img_id])]  # (2,8)表示一张图有两个框

    for index, row in annos.iterrows():  # 一张图的所有annotation信息
        bbox = row["bbox"]
        category_id = row["category_id"]
        # cate_name = categories[trans_id(category_id)]
        cate_name = cat[category_id - 1]['name']

        # add new object
        xml_content.append("<object>")
        xml_content.append("<name>" + cate_name + "</name>")
        xml_content.append("<pose>Unspecified</pose>")
        xml_content.append("<truncated>0</truncated>")
        xml_content.append("<difficult>0</difficult>")
        xml_content.append("<bndbox>")
        xml_content.append("<xmin>" + str(int(bbox[0])) + "</xmin>")
        xml_content.append("<ymin>" + str(int(bbox[1])) + "</ymin>")
        xml_content.append("<xmax>" + str(int(bbox[0] + bbox[2])) + "</xmax>")
        xml_content.append("<ymax>" + str(int(bbox[1] + bbox[3])) + "</ymax>")
        xml_content.append("</bndbox>")
        xml_content.append("</object>")
    xml_content.append("</annotation>")

    x = xml_content
    xml_content = [x[i] for i in range(0, len(x)) if x[i] != "\n"]
    ### list存入文件
    xml_path = os.path.join(xml_dir, file_name.replace('.jpg', '.xml'))
    with open(xml_path, 'w+', encoding="utf8") as f:
        f.write('\n'.join(xml_content))
    xml_content[:] = []

成功运行!

3. 将多个xml文件转换为YOLO所需的txt文件

里面的类别看Readme文件,其中thermal类别比rgb类别多了dog和deer,生成txt注意区分

不过为了后续类别对应,我统一都写成thermal的类别了

复制代码
# xml_to_yolo_txt.py
# 此代码和VOC_KITTI文件夹同目录
import os
import xml.etree.ElementTree as ET
# 这里的类名为我们xml里面的类名,顺序a按照Readme文件,或者也可以不考虑顺序
# 其中thermal类别比rgb类别多了dog和deer,生成txt注意区分
class_names = ['person','bike','car','motor', 'bus', 'train','truck','light','hydrant', 'sign','dog','deer',
               'skateboard','stroller', 'scooter', 'other vehicle']
# class_names = ['person','bike','car','motor', 'bus', 'train','truck','light','hydrant', 'sign',
#                'skateboard','stroller','scooter','other vehicle' ]
# xml文件路径
path = 'G:/红外数据集-FLIR2/FLIR2_yolo_xml/images_rgb_train/data/'
# 转换一个xml文件为txt
def single_xml_to_txt(xml_file):
    tree = ET.parse(os.path.join(path, xml_file))
    root = tree.getroot()
    # 保存的txt文件路径
    txt_file = os.path.join('G:/红外数据集-FLIR2/FLIR2_yolo/images_rgb_train/data/', xml_file.split('.')[0]+'.txt')
    with open(txt_file, 'w') as txt_file:
        for member in root.findall('object'):
            #filename = root.find('filename').text
            picture_width = int(root.find('size')[0].text)
            picture_height = int(root.find('size')[1].text)
            class_name = member[0].text
            # 类名对应的index
            class_num = class_names.index(class_name)

            box_x_min = int(member[4][0].text) # 左上角横坐标
            box_y_min = int(member[4][1].text) # 左上角纵坐标
            box_x_max = int(member[4][2].text) # 右下角横坐标
            box_y_max = int(member[4][3].text) # 右下角纵坐标
            # 转成相对位置和宽高
            x_center = float(box_x_min + box_x_max) / (2 * picture_width)
            y_center = float(box_y_min + box_y_max) / (2 * picture_height)
            width = float(box_x_max - box_x_min) /  picture_width
            height = float(box_y_max - box_y_min) /  picture_height
            # print(class_num, x_center, y_center, width, height)
            txt_file.write(str(class_num) + ' ' + str(x_center) + ' ' + str(y_center) + ' ' + str(width) + ' ' + str(height) + '\n')
# 转换文件夹下的所有xml文件为txt
def dir_xml_to_txt(path):
    files = os.listdir(path)
    for xml_file in files:
        single_xml_to_txt(xml_file)
dir_xml_to_txt(path)

4,整理成yolo的txt格式

一般yolo的格式如下:

因此将上面生成的文件分别整理成图片的格式,然后仿照./data/文件夹下的yaml文件,自己写一个数据yaml:此时的class类别必须和上面生成txt的类别顺序一致。

复制代码
train: G:/yolo_FLIR2/FLIR2_yolo_thermal/images/train
val: G:/yolo_FLIR2/FLIR2_yolo_thermal/images/val
test: G:/yolo_FLIR2/FLIR2_yolo_thermal/images/test

# Classes
names:
  0: person
  1: bike 
  2: car
  3: motor
  4: bus
  5: train
  6: truck
  7: light
  8: hydrant
  9: sign
  10: dog
  11: deer
  12: skateboard
  13: stroller 
  14: scooter 
  15: other vehicle
相关推荐
智驱力人工智能2 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
工程师老罗2 小时前
YOLOv1 核心结构解析
yolo
Lun3866buzha2 小时前
YOLOv10-BiFPN融合:危险物体检测与识别的革新方案,从模型架构到实战部署全解析
yolo
Katecat996633 小时前
YOLOv8-MambaOut在电子元器件缺陷检测中的应用与实践_1
yolo
工程师老罗4 小时前
YOLOv1 核心知识点笔记
笔记·yolo
工程师老罗9 小时前
基于Pytorch的YOLOv1 的网络结构代码
人工智能·pytorch·yolo
学习3人组12 小时前
YOLO模型集成到Label Studio的MODEL服务
yolo
孤狼warrior12 小时前
YOLO目标检测 一千字解析yolo最初的摸样 模型下载,数据集构建及模型训练代码
人工智能·python·深度学习·算法·yolo·目标检测·目标跟踪
水中加点糖14 小时前
小白都能看懂的——车牌检测与识别(最新版YOLO26快速入门)
人工智能·yolo·目标检测·计算机视觉·ai·车牌识别·lprnet
前端摸鱼匠1 天前
YOLOv8 环境配置全攻略:Python、PyTorch 与 CUDA 的和谐共生
人工智能·pytorch·python·yolo·目标检测