YOLO航拍车辆和行人识别
图片数量9695,标注为xml和txt格式;
class:car,pedestrian,truck,bus
用于yolo,Python,目标检测,机器学习,人工智能,深度学习,车辆识别,公交车识别,货车识别,行人识别,无人机航拍识别
数据集名称
YOLO航拍车辆和行人识别数据集
数据集描述
该数据集是一个专门用于训练和评估基于YOLO(You Only Look Once)架构的目标检测模型的数据集,旨在帮助研究人员和开发者在无人机航拍图像中识别车辆(包括轿车、卡车、公交车)和行人。数据集包含9695张高质量的航拍图片,并提供了详细的边界框标注信息,支持直接用于训练目标检测模型。通过高质量的数据和详细的标注信息,该数据集为开发高效且准确的目标检测系统提供了坚实的基础。
数据规模
- 总样本数量:9695张图片
- 标注格式:
- Pascal VOC XML格式
- YOLO txt格式
图像特性
- 多样化场景:覆盖了多种城市和乡村环境下的航拍图像,包括不同的天气条件、光照条件和背景。
- 高质量手工标注:每张图像都有详细的边界框标注,支持直接用于训练目标检测模型。
- 多类别支持:主要关注四类目标:car(轿车)、pedestrian(行人)、truck(卡车)、bus(公交车)。
- 无需预处理:数据集已经过处理,可以直接用于训练,无需额外的数据预处理步骤。
应用场景
- 智能监控:自动检测航拍图像中的车辆和行人,辅助管理人员进行交通监控和管理。
- 无人机应用:集成到无人机系统中,实现对地面目标的实时检测和跟踪。
- 科研分析:用于研究目标检测算法在特定应用场景中的表现,特别是在复杂背景和高视角条件下的鲁棒性。
- 教育与培训:可用于安全相关的教育和培训项目,帮助学生和从业人员更好地理解航拍图像中的目标检测技术。
- 自动化管理:集成到智能交通管理系统中,实现对道路状况的自动化监测和管理。
数据集结构
典型的数据集目录结构如下:
1aerial_vehicle_pedestrian_dataset/
2├── images/
3│ ├── img_00001.jpg
4│ ├── img_00002.jpg
5│ └── ...
6├── annotations/
7│ ├── img_00001.xml # Pascal VOC XML格式
8│ ├── img_00002.xml
9│ └── ...
10├── labels/ # YOLO txt格式
11│ ├── img_00001.txt
12│ ├── img_00002.txt
13│ └── ...
14├── scripts/
15│ ├── convert_voc_to_yolo.py
16│ ├── train_yolo.py
17│ ├── evaluate_yolo.py
18│ ├── visualize_annotations.py
19│ └── data_augmentation.py
20├── README.txt # 数据说明文件
数据说明
- 检测目标:以Pascal VOC XML格式和YOLO txt格式进行标注。
- 数据集内容:
- 总共9695张图片,每张图片都带有相应的XML和txt标注文件。
- 标签类型:
- 边界框 (Bounding Box)
- 数据增广:数据集未做数据增广,用户可以根据需要自行进行数据增广。
- 无需预处理:数据集已经过处理,可以直接用于训练,无需额外的数据预处理步骤。
示例代码
以下是一些常用脚本的示例代码,包括将VOC格式转换为YOLO格式、训练YOLO模型、评估模型性能、可视化标注以及数据增强。
脚本1: 将VOC格式转换为YOLO格式
1# convert_voc_to_yolo.py
2import os
3import xml.etree.ElementTree as ET
4
5def convert_voc_to_yolo(xml_file, image_size):
6 tree = ET.parse(xml_file)
7 root = tree.getroot()
8 yolo_lines = []
9
10 for obj in root.findall('object'):
11 name = obj.find('name').text
12 bbox = obj.find('bndbox')
13 xmin = int(bbox.find('xmin').text)
14 ymin = int(bbox.find('ymin').text)
15 xmax = int(bbox.find('xmax').text)
16 ymax = int(bbox.find('ymax').text)
17
18 x_center = (xmin + xmax) / 2.0 / image_size[0]
19 y_center = (ymin + ymax) / 2.0 / image_size[1]
20 width = (xmax - xmin) / image_size[0]
21 height = (ymax - ymin) / image_size[1]
22
23 class_id = 0 if name == 'car' else 1 if name == 'pedestrian' else 2 if name == 'truck' else 3 # 假设只有四个类别
24 yolo_line = f"{class_id} {x_center} {y_center} {width} {height}\n"
25 yolo_lines.append(yolo_line)
26
27 return yolo_lines
28
29def main():
30 voc_dir = 'path/to/annotations'
31 yolo_dir = 'path/to/labels'
32 image_dir = 'path/to/images'
33
34 if not os.path.exists(yolo_dir):
35 os.makedirs(yolo_dir)
36
37 for xml_file in os.listdir(voc_dir):
38 if xml_file.endswith('.xml'):
39 image_path = os.path.join(image_dir, xml_file.replace('.xml', '.jpg'))
40 image = Image.open(image_path)
41 image_size = image.size
42
43 yolo_lines = convert_voc_to_yolo(os.path.join(voc_dir, xml_file), image_size)
44 with open(os.path.join(yolo_dir, xml_file.replace('.xml', '.txt')), 'w') as f:
45 f.writelines(yolo_lines)
46
47if __name__ == "__main__":
48 main()
脚本2: 训练YOLO模型
1# train_yolo.py
2import os
3import torch
4from yolov5 import train
5
6def main():
7 data_yaml = 'path/to/data.yaml' # 包含数据集路径和类别的配置文件
8 model_yaml = 'path/to/model.yaml' # 模型配置文件
9 weights = 'path/to/weights.pt' # 预训练权重(可选)
10 epochs = 100
11 batch_size = 8
12 img_size = 640
13
14 train.run(
15 data=data_yaml,
16 cfg=model_yaml,
17 weights=weights,
18 epochs=epochs,
19 batch_size=batch_size,
20 imgsz=img_size
21 )
22
23if __name__ == "__main__":
24 main()
脚本3: 评估YOLO模型
1# evaluate_yolo.py
2import os
3import torch
4from yolov5 import val
5
6def main():
7 data_yaml = 'path/to/data.yaml' # 包含数据集路径和类别的配置文件
8 weights = 'path/to/best.pt' # 训练好的模型权重
9 img_size = 640
10
11 val.run(
12 data=data_yaml,
13 weights=weights,
14 imgsz=img_size
15 )
16
17if __name__ == "__main__":
18 main()
脚本4: 可视化标注
1# visualize_annotations.py
2import os
3import cv2
4import numpy as np
5from PIL import Image
6import xml.etree.ElementTree as ET
7
8def load_image_and_boxes(image_path, annotation_path):
9 # 读取图像
10 image = Image.open(image_path).convert('RGB')
11
12 # 解析Pascal VOC格式的XML标注文件
13 tree = ET.parse(annotation_path)
14 root = tree.getroot()
15 boxes = []
16 for obj in root.findall('object'):
17 class_name = obj.find('name').text
18 bbox = obj.find('bndbox')
19 xmin = int(bbox.find('xmin').text)
20 ymin = int(bbox.find('ymin').text)
21 xmax = int(bbox.find('xmax').text)
22 ymax = int(bbox.find('ymax').text)
23 boxes.append([class_name, xmin, ymin, xmax, ymax])
24
25 return image, boxes
26
27def show_image_with_boxes(image, boxes):
28 img = np.array(image)
29 for box in boxes:
30 class_name, xmin, ymin, xmax, ymax = box
31 cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)
32 label = f'{class_name}'
33 cv2.putText(img, label, (xmin, ymin - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
34
35 cv2.imshow('Image with Boxes', img)
36 cv2.waitKey(0)
37 cv2.destroyAllWindows()
38
39def main():
40 images_dir = 'path/to/images'
41 annotations_dir = 'path/to/annotations'
42
43 # 获取图像列表
44 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg')]
45
46 # 随机选择一张图像
47 selected_image = np.random.choice(image_files)
48 image_path = os.path.join(images_dir, selected_image)
49 annotation_path = os.path.join(annotations_dir, selected_image.replace('.jpg', '.xml'))
50
51 # 加载图像和边界框
52 image, boxes = load_image_and_boxes(image_path, annotation_path)
53
54 # 展示带有边界框的图像
55 show_image_with_boxes(image, boxes)
56
57if __name__ == "__main__":
58 main()
脚本5: 数据增强
1# data_augmentation.py
2import os
3import cv2
4import numpy as np
5import albumentations as A
6from PIL import Image
7import xml.etree.ElementTree as ET
8
9def load_image_and_boxes(image_path, annotation_path):
10 # 读取图像
11 image = Image.open(image_path).convert('RGB')
12 image = np.array(image)
13
14 # 解析Pascal VOC格式的XML标注文件
15 tree = ET.parse(annotation_path)
16 root = tree.getroot()
17 boxes = []
18 for obj in root.findall('object'):
19 class_name = obj.find('name').text
20 bbox = obj.find('bndbox')
21 xmin = int(bbox.find('xmin').text)
22 ymin = int(bbox.find('ymin').text)
23 xmax = int(bbox.find('xmax').text)
24 ymax = int(bbox.find('ymax').text)
25 boxes.append([xmin, ymin, xmax, ymax, class_name])
26
27 return image, boxes
28
29def save_augmented_data(augmented_image, augmented_boxes, output_image_path, output_annotation_path):
30 # 保存增强后的图像
31 augmented_image = Image.fromarray(augmented_image)
32 augmented_image.save(output_image_path)
33
34 # 保存增强后的标注
35 tree = ET.parse(output_annotation_path)
36 root = tree.getroot()
37 for obj, new_box in zip(root.findall('object'), augmented_boxes):
38 bbox = obj.find('bndbox')
39 bbox.find('xmin').text = str(new_box[0])
40 bbox.find('ymin').text = str(new_box[1])
41 bbox.find('xmax').text = str(new_box[2])
42 bbox.find('ymax').text = str(new_box[3])
43
44 tree.write(output_annotation_path)
45
46def augment_data(image, boxes):
47 transform = A.Compose([
48 A.RandomRotate90(p=0.5),
49 A.HorizontalFlip(p=0.5),
50 A.VerticalFlip(p=0.5),
51 A.RandomBrightnessContrast(p=0.2),
52 A.HueSaturationValue(p=0.2)
53 ], bbox_params=A.BboxParams(format='pascal_voc', label_fields=['category_ids']))
54
55 category_ids = [box[-1] for box in boxes]
56 bboxes = [box[:-1] for box in boxes]
57
58 transformed = transform(image=image, bboxes=bboxes, category_ids=category_ids)
59 transformed_image = transformed['image']
60 transformed_bboxes = transformed['bboxes']
61
62 return transformed_image, transformed_bboxes
63
64def main():
65 images_dir = 'path/to/images'
66 annotations_dir = 'path/to/annotations'
67 output_images_dir = 'path/to/augmented_images'
68 output_annotations_dir = 'path/to/augmented_annotations'
69
70 if not os.path.exists(output_images_dir):
71 os.makedirs(output_images_dir)
72
73 if not os.path.exists(output_annotations_dir):
74 os.makedirs(output_annotations_dir)
75
76 # 获取图像列表
77 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg')]
78
79 for image_file in image_files:
80 image_path = os.path.join(images_dir, image_file)
81 annotation_path = os.path.join(annotations_dir, image_file.replace('.jpg', '.xml'))
82
83 # 加载图像和边界框
84 image, boxes = load_image_and_boxes(image_path, annotation_path)
85
86 # 增强数据
87 augmented_image, augmented_boxes = augment_data(image, boxes)
88
89 # 保存增强后的数据
90 output_image_path = os.path.join(output_images_dir, image_file)
91 output_annotation_path = os.path.join(output_annotations_dir, image_file.replace('.jpg', '.xml'))
92 save_augmented_data(augmented_image, augmented_boxes, output_image_path, output_annotation_path)
93
94if __name__ == "__main__":
95 main()
项目介绍
项目名称
基于YOLO的航拍车辆和行人识别系统
项目描述
该项目旨在开发一个基于YOLO架构的航拍图像中的车辆和行人识别系统。通过使用上述数据集,我们将训练一个高效的深度学习模型,能够在无人机拍摄的高分辨率图像中实时检测并分类轿车、行人、卡车和公交车。项目的主要目标是提高交通管理和城市规划的效率,同时为无人机应用提供强大的视觉感知能力。
项目目标
- 实时检测:实现对航拍图像中车辆和行人的实时检测。
- 高精度分类:能够准确地区分不同类型的车辆(轿车、卡车、公交车)和行人。
- 鲁棒性:在不同天气条件、光照条件和背景下保持良好的检测性能。
- 易用性:提供易于部署和使用的接口,方便集成到现有的无人机系统中。
项目结构
1aerial_vehicle_pedestrian_detection_project/
2├── data/
3│ ├── aerial_vehicle_pedestrian_dataset/
4│ │ ├── images/
5│ │ ├── annotations/
6│ │ ├── labels/
7│ │ ├── scripts/
8│ │ └── README.txt
9├── models/
10│ ├── yolov5s.pt # 预训练模型
11│ ├── best.pt # 最佳训练模型
12├── config/
13│ ├── data.yaml # 数据集配置文件
14│ ├── model.yaml # 模型配置文件
15├── scripts/
16│ ├── convert_voc_to_yolo.py
17│ ├── train_yolo.py
18│ ├── evaluate_yolo.py
19│ ├── visualize_annotations.py
20│ ├── data_augmentation.py
21│ ├── inference.py # 推理脚本
22├── notebooks/
23│ ├── data_exploration.ipynb # 数据探索笔记本
24│ ├── model_training.ipynb # 模型训练笔记本
25│ ├── model_evaluation.ipynb # 模型评估笔记本
26├── requirements.txt # 依赖库
27└── README.md # 项目说明文件
项目流程
-
数据准备:
- 下载并解压数据集。
- 使用
convert_voc_to_yolo.py
脚本将VOC格式的标注转换为YOLO格式。
-
数据探索:
- 使用
data_exploration.ipynb
笔记本探索数据集,了解数据分布和质量。
- 使用
-
数据增强:
- 使用
data_augmentation.py
脚本对数据进行增强,增加数据多样性。
- 使用
-
模型训练:
- 使用
train_yolo.py
脚本训练YOLO模型。 - 根据需要调整超参数和模型配置。
- 使用
-
模型评估:
- 使用
evaluate_yolo.py
脚本评估模型性能。 - 生成混淆矩阵和分类报告。
- 使用
-
推理和应用:
- 使用
inference.py
脚本进行实时检测和分类。 - 将模型集成到无人机系统或其他应用中。
- 使用
-
结果可视化:
- 使用
visualize_annotations.py
脚本可视化检测结果。
- 使用
改进方向
如果您已经使用上述方法对该数据集进行了训练,并且认为还有改进空间,以下是一些可能的改进方向:
-
数据增强:
- 进一步增加数据增强策略,例如旋转、翻转、缩放、颜色抖动等,以提高模型的泛化能力。
- 使用混合增强技术,如MixUp、CutMix等,以增加数据多样性。
-
模型优化:
- 调整模型超参数,例如学习率、批量大小、优化器等,以找到最佳配置。
- 尝试使用不同的骨干网络(Backbone),例如EfficientNet、ResNet等,以提高特征提取能力。
- 引入注意力机制,如SENet、CBAM等,以增强模型对关键区域的关注。
-
损失函数:
- 尝试使用不同的损失函数,例如Focal Loss、IoU Loss等,以改善模型的收敛性能。
- 结合多种损失函数,例如分类损失和回归损失的组合,以平衡不同类型的任务。
-
后处理:
- 使用非极大值抑制(NMS)的改进版本,如Soft-NMS、DIoU-NMS等,以提高检测结果的质量。
- 引入边界框回归的改进方法,如GIoU、CIoU等,以提高定位精度。
-
迁移学习:
- 使用预训练模型进行微调,利用大规模数据集(如COCO、ImageNet)上的预训练权重,加快收敛速度并提高性能。
-
集成学习:
- 使用多个模型进行集成学习,通过投票或加权平均的方式提高最终的检测效果。
通过上述方法,可以进一步提升模型在航拍车辆和行人识别任务上的性能。