基于 DroneVehicle 数据集的 YOLOv11 无人机车辆目标检测
使用 YOLOv11 在 DroneVehicle 数据集上进行无人机视角车辆目标检测的完整流程。内容包括数据集介绍与下载、图像白边裁剪预处理、标签格式转换(COCO 转 VOC 再转 YOLO)、训练集划分策略以及模型训练与预测结果验证。重点解决了标注框越界导致的坐标异常问题,并展示了可见光下的检测效果。

使用 YOLOv11 在 DroneVehicle 数据集上进行无人机视角车辆目标检测的完整流程。内容包括数据集介绍与下载、图像白边裁剪预处理、标签格式转换(COCO 转 VOC 再转 YOLO)、训练集划分策略以及模型训练与预测结果验证。重点解决了标注框越界导致的坐标异常问题,并展示了可见光下的检测效果。

DroneVehicle 数据集是由天津大学收集、标注的大型无人机航拍车辆数据集。 DroneVehicle 数据集由无人机采集的共 56,878 幅图像组成,其中一半为 RGB 图像,其余为红外图像。我们对五个类别进行了带有方向性边界框的丰富标注。其中,汽车 car 在 RGB 图像中有 389,779 个标注,在红外图像中有 428,086 个标注;卡车 truck 在 RGB 图像中有 22,123 个标注,在红外图像中有 25,960 个标注;公交车 bus 在 RGB 图像中有 15,333 个标注,在红外图像中有 16,590 个标注;面包车 van 在 RGB 图像中有 11,935 个标注,在红外图像中有 12,708 个标注;货车 freight_car 在 RGB 图像中有 13,400 个标注,在红外图像中有 17,173 个标注。
参见作者 Github:https://github.com/VisDrone/DroneVehicle
在 DroneVehicle 中,为了标注图片边界上的物体,作者在每张图片的上下左右四边设置了宽度为 100 像素的白色边框,这样下载的图片尺寸就是 840 x 712。在训练我们的检测网络时,我们可以进行预处理,去除周围的白色边框,并将图像尺寸改为 640 x 512。

处理前后对比。
去除白边代码:
import numpy as np
import cv2
import os
from tqdm import tqdm
def create_file(output_dir_vi, output_dir_ir):
if not os.path.exists(output_dir_vi):
os.makedirs(output_dir_vi)
if not os.path.exists(output_dir_ir):
os.makedirs(output_dir_ir)
print(f'Created folder:({output_dir_vi}); ({output_dir_ir})')
def update(input_img_path, output_img_path):
image = cv2.imread(input_img_path)
cropped = image[100:612, 100:740] # 裁剪坐标为 [y0:y1, x0:x1]
cv2.imwrite(output_img_path, cropped)
dataset_dir_vi = r'valimg' # 处理前可见光图片目录
output_dir_vi = r'valimg2' # 处理后可见光图片目录
dataset_dir_ir = r'valimgr' # 处理前红外光图片目录
output_dir_ir = r'valimgr2' # 处理后红外光图片目录
# 检查文件夹是否存在,如果不存在则创建
create_file(output_dir_vi, output_dir_ir)
# 获得需要转化的图片路径并生成目标路径
image_filenames_vi = [(os.path.join(dataset_dir_vi, x), os.path.join(output_dir_vi, x)) for x in os.listdir(dataset_dir_vi)]
image_filenames_ir = [(os.path.join(dataset_dir_ir, x), os.path.join(output_dir_ir, x)) for x in os.listdir(dataset_dir_ir)]
# 转化所有图片
print('Start transforming vision images...')
for path in tqdm(image_filenames_vi):
update(path[0], path[1])
print('Start transforming infrared images...')
for path in tqdm(image_filenames_ir):
update(path[0], path[1])

这里我用的是 X-AnyLabeling 作为标注软件。

处理该数据集标签文件时发现部分检测框的位置可能会在图片边缘外面,导致直接转成 YOLO 的时候,会出现负坐标或者大于 1 的坐标值,这样会导致模型训练不了或者存在一定问题,所以对该部分检测框在转换时需进行特殊处理。注意:X-AnyLabeling 也可以直接导出 YOLO 格式标签,但是经测试 X-AnyLabeling 也没有处理大于 1 的坐标值。
xml2txt.py
import xml.etree.ElementTree as ET
import shutil
import os
import imagesize
# 定义识别目标或类集合
object = 'datasets'
# 根据自定义的数据集名称
if os.path.exists("./%s/labels/" % object):
# 如果文件存在
shutil.rmtree("./%s/labels/" % object)
os.makedirs("./%s/labels/" % object)
else:
os.makedirs("./%s/labels/" % object)
sets = ['train', 'val'] # 修改类别 (自定义)
classes = ["car", "truck", "bus", "van", "freight_car"]
def convert(size, box):
# 坐标信息归一化至 0-1
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return (x, y, w, h)
def convert_annotation(image_id):
in_file = open( % (, image_id))
out_file = ( % (, image_id), )
image_file = ( % (, image_id))
( , in_file)
tree = ET.parse(in_file)
root = tree.getroot()
size = root.find()
w, h = imagesize.get(image_file.name)
obj root.():
difficult = obj.find().text
cls = obj.find().text
cls classes (difficult) == :
cls_id = classes.index(cls)
xmlbox = obj.find()
xmin = (xmlbox.find().text)
xmin = xmin xmin >=
xmax = (xmlbox.find().text)
xmax = xmax xmax <= w (w)
ymin = (xmlbox.find().text)
ymin = ymin ymin >=
ymax = (xmlbox.find().text)
ymax = ymax ymax <= h (h)
b = (xmin, xmax, ymin, ymax)
bb = convert((w, h), b)
out_file.write((cls_id) + + .join([(a) a bb]) + )
image_set sets:
os.path.exists( % ):
os.makedirs( % )
image_ids = ( % (, image_set)).read().strip().split()
list_file = ( % (, image_set), )
image_id image_ids:
list_file.write( % (image_id))
convert_annotation(image_id)
list_file.close()
我在这里只处理可见光部分的数据集,红外光数据集处理跟该处理方式相同。 我的处理思路: 1)因为不需要测试集,所以我将 val 验证集的 1469 个数据和 test 测试集 8980 个数据的 20% 的数据作为我的验证集,即 1469+89800.2=3265 个数据验证集。 2)将 train 训练集的 17990 个数据和 test 测试集 8980 个数据的 80% 的数据作为我的训练集,即 17990+89800.8=25174 个数据训练集。 3)整理我的训练集和验证集

此时数据集已是 YOLO 格式,可以直接训练。
我选择了 yolo11s 的网络权重进行模型训练,训练 100 个 epoch 结果如下:

可以看到训练结果还不错。
验证集上标签可视化:



第一张图片是 val 验证集中找的,第二张图片是网络上随便找的,检测结果比较理想。
虽然从训练结果上看效果还不错,但是仅针对于该种无人机航拍视角下,如果是斜视视角则效果较差。其次红外光下的检测效果目前还没测过,以及可见光和红外光融合检测效果也未经测试。
需要注意的点:处理白边、处理在图片边缘外的检测框问题。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online