【目标检测】Visdrone数据集和CARPK数据集预处理

news2024/9/17 8:45:54

之前的博文【目标检测】YOLOv5跑通VisDrone数据集对Visdrone数据集简介过,这里不作复述,本文主要对Visdrone数据集和CARPK数据集进行目标提取和过滤。

需求描述

本文需要将Visdrone数据集中有关车和人的数据集进行提取和合并,车标记为类别0,人标记为类别1,并转换成YOLO支持的txt格式。

Visdrone数据集

Visdrone数据集转换成YOLO的txt格式

首先对原始数据集做一个格式转换,下面这段代码延用官方提供的转换脚本。

from utils.general import download, os, Path


def visdrone2yolo(dir):
    from PIL import Image
    from tqdm import tqdm

    def convert_box(size, box):
        # Convert VisDrone box to YOLO xywh box
        dw = 1. / size[0]
        dh = 1. / size[1]
        return (box[0] + box[2] / 2) * dw, (box[1] + box[3] / 2) * dh, box[2] * dw, box[3] * dh

    (dir / 'labels').mkdir(parents=True, exist_ok=True)  # make labels directory
    pbar = tqdm((dir / 'annotations').glob('*.txt'), desc=f'Converting {dir}')
    for f in pbar:
        img_size = Image.open((dir / 'images' / f.name).with_suffix('.jpg')).size
        lines = []
        with open(f, 'r') as file:  # read annotation.txt
            for row in [x.split(',') for x in file.read().strip().splitlines()]:
                if row[4] == '0':  # VisDrone 'ignored regions' class 0
                    continue
                cls = int(row[5]) - 1  # 类别号-1
                box = convert_box(img_size, tuple(map(int, row[:4])))
                lines.append(f"{cls} {' '.join(f'{x:.6f}' for x in box)}\n")
                with open(str(f).replace(os.sep + 'annotations' + os.sep, os.sep + 'labels' + os.sep), 'w') as fl:
                    fl.writelines(lines)  # write label.txt


dir = Path(r'E:\Dataset\VisDrone')  # datasets文件夹下Visdrone2019文件夹目录
# Convert
for d in 'VisDrone2019-DET-train', 'VisDrone2019-DET-val', 'VisDrone2019-DET-test-dev':
    visdrone2yolo(dir / d)  # convert VisDrone annotations to YOLO labels

标签可视化

对txt标签进行可视化,查看过滤之前的效果。

import os
import numpy as np
import cv2

# 修改输入图片文件夹
img_folder = "image"
img_list = os.listdir(img_folder)
img_list.sort()
# 修改输入标签文件夹
label_folder = "labels2"
label_list = os.listdir(label_folder)
label_list.sort()
# 输出图片文件夹位置
path = os.getcwd()
output_folder = path + '/' + str("output")
os.mkdir(output_folder)

# 坐标转换
def xywh2xyxy(x, w1, h1, img):
    label, x, y, w, h = x
    # print("原图宽高:\nw1={}\nh1={}".format(w1, h1))
    # 边界框反归一化
    x_t = x * w1
    y_t = y * h1
    w_t = w * w1
    h_t = h * h1
    # print("反归一化后输出:\n第一个:{}\t第二个:{}\t第三个:{}\t第四个:{}\t\n\n".format(x_t, y_t, w_t, h_t))
    # 计算坐标
    top_left_x = x_t - w_t / 2
    top_left_y = y_t - h_t / 2
    bottom_right_x = x_t + w_t / 2
    bottom_right_y = y_t + h_t / 2

    # print('标签:{}'.format(labels[int(label)]))
    # print("左上x坐标:{}".format(top_left_x))
    # print("左上y坐标:{}".format(top_left_y))
    # print("右下x坐标:{}".format(bottom_right_x))
    # print("右下y坐标:{}".format(bottom_right_y))
    # 绘制矩形框
    # cv2.rectangle(img, (int(top_left_x), int(top_left_y)), (int(bottom_right_x), int(bottom_right_y)), colormap[1], 2)
    # (可选)给不同目标绘制不同的颜色框
    if int(label) == 0:
        cv2.rectangle(img, (int(top_left_x), int(top_left_y)), (int(bottom_right_x), int(bottom_right_y)), (0, 255, 0), 2)
    elif int(label) == 1:
        cv2.rectangle(img, (int(top_left_x), int(top_left_y)), (int(bottom_right_x), int(bottom_right_y)), (255, 0, 0), 2)
    else:
        cv2.rectangle(img, (int(top_left_x), int(top_left_y)), (int(bottom_right_x), int(bottom_right_y)), (0, 0, 0), 2)

    return img


if __name__ == '__main__':
    for i in range(len(img_list)):
        image_path = img_folder + "/" + img_list[i]
        label_path = label_folder + "/" + label_list[i]
        # 读取图像文件
        img = cv2.imread(str(image_path))
        h, w = img.shape[:2]
        # 读取 labels
        with open(label_path, 'r') as f:
            lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=np.float32)
        # 绘制每一个目标
        for x in lb:
            # 反归一化并得到左上和右下坐标,画出矩形框
            img = xywh2xyxy(x, w, h, img)
        """
        # 直接查看生成结果图
        cv2.imshow('show', img)
        cv2.waitKey(0)
        """
        cv2.imwrite(output_folder + '/' + '{}.png'.format(image_path.split('/')[-1][:-4]), img)

可视化效果如图所示:
注:该数据集对人的姿态还进行区分,行走状态的人划分为pedestrian,其它姿态(比如躺下或坐下)标记为people。

在这里插入图片描述

过滤标签

具体过滤规则:

  • 合并car、van、truck、bus为car(0)
  • 合并pedestrian,people为person(1)
  • 舍弃其它类别
import os
import numpy as np
from tqdm import tqdm

# Visdrone类别
# names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor' ]

# 修改输入标签文件夹
label_folder = "labels"
label_list = os.listdir(label_folder)

# 标签输出文件夹
label_output = "labels2"

# class_set
car_set = [3, 4, 5, 8]
person_set = [0, 1]

if __name__ == '__main__':
    for label_file in tqdm(os.listdir(label_folder)):
        # 读取 labels
        with open(os.path.join(label_folder, label_file), 'r') as f:
            lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=np.float32)
        # 写入 labels
        with open(os.path.join(label_output, label_file), 'a') as f:
            for obj in lb:
                # 若是行人,修改类别为1
                if int(obj[0]) in person_set:
                    obj[0] = 1
                    f.write(('%g ' * 5).rstrip() % tuple(obj) + '\n')
                # 若是车辆,修改类别为0
                elif int(obj[0]) in car_set:
                    obj[0] = 0
                    f.write(('%g ' * 5).rstrip() % tuple(obj) + '\n')

过滤之后的效果如图所示:

在这里插入图片描述

CARPK数据集

CARPK数据集是无人机在40米高空拍摄的汽车数据集,里面仅包含汽车单一目标。

下载地址:https://github.com/zstar1003/Dataset

原始label格式:

1019 521 1129 571 1
1013 583 1120 634 1

对应含义为: xmin, ymin, xmax, ymax,cls

处理脚本:

import os
import numpy as np
from tqdm import tqdm

# 修改输入标签文件夹
# label_folder = r"E:\Dataset\CARPK_devkit\data\Annotations"
label_folder = r"annotations"
label_list = os.listdir(label_folder)

# 标签输出文件夹
label_output = r"labels"

# 图像宽高
img_width = 1280
img_height = 720

if __name__ == '__main__':
    for label_file in tqdm(os.listdir(label_folder)):
        # 读取 labels
        with open(os.path.join(label_folder, label_file), 'r') as f:
            lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=int)
        for obj in lb:
            class_index = obj[4]
            xmin, ymin, xmax, ymax = obj[0], obj[1], obj[2], obj[3]
            # 将box信息转换到yolo格式
            xcenter = xmin + (xmax - xmin) / 2
            ycenter = ymin + (ymax - ymin) / 2
            w = xmax - xmin
            h = ymax - ymin
            # 绝对坐标转相对坐标,保存6位小数
            xcenter = round(xcenter / img_width, 6)
            ycenter = round(ycenter / img_height, 6)
            w = round(w / img_width, 6)
            h = round(h / img_height, 6)
            info = [str(i) for i in [class_index, xcenter, ycenter, w, h]]
            # 写入 labels
            with open(os.path.join(label_output, label_file), 'a') as f:
                # 若文件不为空,添加换行
                if os.path.getsize(os.path.join(label_output, label_file)):
                    f.write("\n" + " ".join(info))
                else:
                    f.write(" ".join(info))

可视化验证转换效果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1145083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软考系列(系统架构师)- 2010年系统架构师软考案例分析考点

试题一 软件系统架构选择 【问题1】(7分) 在实际的软件项目开发中,采用恰当的架构风格是项目成功的保证。请用200字以内的文字说明什么是软件架构风格,并对主程序-子程序和管道-过滤器这两种架构风格的特点进行描述。 软件架构风…

【C语言数据结构——————排序(1万字)】

文章目录 排序的概念 常见排序算法分类冒泡排序 时间复杂度稳定性 原理实现插入排序 时间复杂度稳定性实现选择排序 时间复杂度稳定性实现希尔排序 时间复杂度稳定性希尔排序的算法思想实现 优化快速排序 时间复杂度空间复杂度稳定性实现 三数取中优化归并排序 时间复杂度空间复…

windows下OOM排查

如下有一段代码 package com.lm.demo.arthas.controller;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.A…

Notepad++安装插件和配置快捷键

Notepad是一款轻量级、开源的文件编辑工具,可以编辑、浏览文本文件、二进制文件、.cpp、.java、*.cs等文件。Notepad每隔1个月,就有一个新版本,其官网是: https://github.com/notepad-plus-plus/notepad-plus-plus。这里介绍其插件…

maven之父子工程版本控制案例实战,及拓展groupId和artifactId的含义

<parent>标签 用于父子工程项目&#xff0c;什么是父子工程&#xff1f; 顾名思义&#xff0c;maven父子项目是一个有一个父项目&#xff0c;父项目下面又有很多子项目的maven工程&#xff0c;当然&#xff0c;子项目下面还可以添加子项目&#xff0c;从而形成一个树形…

GPS学习(一):在ROS2中将GPS经纬度数据转换为机器人ENU坐标系,在RVIZ中显示坐标轨迹

文章目录 一、GPS模块介绍二、坐标转换转换原理参数解释&#xff1a; 增加回调函数效果演示 本文记录在Ubuntu22.04-Humbel中使用NMEA协议GPS模块的过程&#xff0c;使用国产ROS开发板鲁班猫(LubanCat )进行调试。 一、GPS模块介绍 在淘宝找了款性价比较高的轮趣科技GPS北斗双…

AD7321代码SPI接口模数转换连接DAC0832输出verilog

名称&#xff1a;AD7321代码12位ADC&#xff0c;SPI接口模数转换连接DAC0832输出 软件&#xff1a;QuartusII 语言&#xff1a;VHDL 代码功能&#xff1a; 使用VHDL语言编写代码&#xff0c;实现AD7321的控制&#xff0c;将模拟信号转换为数字信号&#xff0c;再经过处理后…

fatfs对于exFAT的使用

f_mkfs的介绍 f_mkfs是FatFs库中的一个函数&#xff0c;用于在指定的磁盘上执行格式化操作。它可以用于创建新的文件系统或重新格式化已有的文件系统。 函数原型如下&#xff1a; FRESULT f_mkfs (const TCHAR* path, // 磁盘路径BYTE opt, // 格式化选项DWORD a…

【QT】点击按钮弹出对话框的注意事项

在stack区创建对话框对象 模态对话框&#xff0c;不可以对其他窗口进行操作。 模态窗口用dlg.exec()显示窗口。 问题代码1: MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);//点击新建按钮&#xff0c;弹出一…

设计模式【Iterator 模式】

Iterator 模式 1.什么是 Iterator 模式 Iterator 模式就是按照顺序遍历数据集合。 2.示例程序 1.Aggregate 接口 Aggregate 接口是要遍历的集合的接口&#xff0c;声明方法 iterator &#xff0c;实现了该接口的类可以通过 iterator 方法遍历数据集合的元素。 public int…

H5游戏分享-全民找房祖名qmxzfzm

H5游戏分享-全民找房祖名qmxzfzm 一开始就比较简单 后面就会越来越难&#xff0c;而且也有时间限制 游戏的源码 <!DOCTYPE html> <html><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,ini…

【神印王座】易军献身为林鑫挡箭,万万没想到林鑫太坑,大跌眼镜

【侵权联系删除】【文/郑尔巴金】 深度爆料&#xff0c;《神印王座》动漫最新剧集中&#xff0c;龙皓晨离开后&#xff0c;恶魔族新的援兵突然出现&#xff0c;使得队友们面临了前所未有的困境。这次战斗中&#xff0c;易军与圣采儿等人决定正面攻击恶魔统领&#xff0c;这无疑…

JVM基础:字节码文件详解①

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Java虚拟机的组成二、字节码文件的组成2.1 为什么要了解字节码文件&#xff1f;2.2 如何“窥探”字节码文件的奥秘&#xff1f;2.2.1 使用工具打开字节码文件2.…

09循环嵌套

循环嵌套顾名思义循环里面套循环 # 循环嵌套顾名思义循环里面套循环a 1 b 0 while a < 10:# print(1, a)b 1while b < a and b < 10:print("%d*%d%d" % (b, a, a * b), end" ")b 1print()a 1format 格式化运算符 只需要填入数据即可 print(…

Mathtype使用指南01:下载与安装

目录 介绍&#xff1a; 安装 介绍&#xff1a; MathType 是一款广泛用于数学和科学文档创建的强大数学编辑工具。它允许用户轻松地在各种文档类型中插入数学方程、符号和公式&#xff0c;是学术界、工程领域、出版界和教育机构中的专业人士常用的工具。下面是关于 MathType 的…

ChineseChess6 2023.10.28

中国象棋残局&#xff1a;黑一卒一车 这红棋好像也是无解哦

如何使用ffmpeg制作透明背景的视频

最近我们尝试在网页上叠加数字人讲解的功能&#xff0c;发现如果直接在网页上放一个矩形的数字人视频&#xff0c;效果会很差&#xff0c;首先是会遮挡很多画面的内容&#xff0c;其次就是不管使用任何任务背景&#xff0c;画面都和后面的网页不是很协调&#xff0c;如图所示&a…

2-多媒体数据压缩国际标准

文章目录 多媒体数据压缩编码的重要性和分类为什么要压缩?计算: 未压缩音频的数据率简答: 环绕声系统-作业题9(简述7.4.3全景声)计算: 未压缩图像的数据量-作业题10(估计尺寸及容量)计算: 未压缩视频的数据率 为什么能压缩?数据压缩编码的两大类无损压缩算法: LZ77-作业题6-(…

Visual Studio Code的下载与安装

Visual Studio Code&#xff08;简称 VS Code&#xff09;是由 Microsoft 开发的免费、开源的文本编辑器&#xff0c;适用于多种操作系统&#xff0c;包括 Windows、macOS 和 Linux。它的设计目标是成为一款轻量级、高效的代码编辑工具&#xff0c;同时提供丰富的扩展和功能&am…

计算机毕业设计 基于SpringBoot大学生就业服务平台的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…