目录
前言
数据集介绍
数据集转换
YOLO代码的下载
YOLO的配置
1.数据集的配置
2.模型的配置
YOLO11模型的训练
其它版本YOLO的训练
前言
遥感技术的快速发展,特别是在高分辨率遥感图像的获取能力上的显著提升,已经大大拓宽了遥感数据在环境监测、灾害评估、城市规划及军事侦察等领域的应用范围。在这些应用中,遥感目标检测作为一项基础而关键的技术,其研究和发展受到了广泛关注。遥感目标检测旨在从遥感图像中自动识别并定位地表特定目标,其挑战在于需要处理大尺寸、高复杂度的图像,并且需要在多变的环境条件下保持高准确率和鲁棒性。随着深度学习技术的快速进步,基于深度学习的目标检测算法,尤其是YOLO系列算法,已经成为遥感目标检测领域研究的热点。YOLO算法以其快速、准确的特点,在实时目标检测领域展现出了显著的优势,而其后续版本的不断优化和改进,进一步提升了在遥感图像上的适用性和性能。
数据集介绍
我们使用NWPU VHR-10数据集实现实现遥感图像目标检测。
NWPU VHR-10数据集是一个专为遥感图像目标检测任务设计的高分辨率(Very High Resolution, VHR)遥感图像数据集。它由西北工业大学遥感图像研究团队(NWPU)发布,广泛用于目标检测与相关研究。数据集图像是从谷歌地球和Vaihingen数据集中裁剪出来的,然后由专家手动注释。Vaihingen数据由德国摄影测量、遥感和地理信息学会(DGPF)提供:http://www.ifp.uni-stuttgart.de/dgpf/DKEPAllg.html.
数据集GitHub链接如下:
GitHub - Gaoshuaikun/NWPU-VHR-10: NWPU VHR-10 datasethttps://github.com/Gaoshuaikun/NWPU-VHR-10?tab=readme-ov-filehttps://github.com/Gaoshuaikun/NWPU-VHR-10?tab=readme-ov-filehttps://github.com/Gaoshuaikun/NWPU-VHR-10?tab=readme-ov-filehttps://github.com/Gaoshuaikun/NWPU-VHR-10?tab=readme-ov-file
也可以通过下面的链接直接下载:
NWPU VHR-10 dataset.rar_免费高速下载|百度网盘-分享无限制https://pan.baidu.com/s/1DWibgMXGbC1V5aAuN54JUA?from=init&pwd=1234https://pan.baidu.com/s/1DWibgMXGbC1V5aAuN54JUA?from=init&pwd=1234https://pan.baidu.com/s/1DWibgMXGbC1V5aAuN54JUA?from=init&pwd=1234https://pan.baidu.com/s/1DWibgMXGbC1V5aAuN54JUA?from=init&pwd=1234
数据集一共有10个类别:
airplane | 飞机 | |
ship | 船 | |
storage tank | 储罐 | |
baseball diamond | 棒球场 | |
tennis court | 网球场 | |
basketball court | 篮球场 | |
ground track field | 地面田径场 | |
harbor | 港口 | |
bridge | 桥 | |
vehicle | 车辆 |
该数据集目录如下:
其中,ground truth目录内是每张图像的标签,negative image set是无标签的图像,我们可以将其用作测试,positive image set是有标签的图像,与ground truth内的txt文件按照文件名一一对应。
标签格式如下:
(575,114),(635,162),1
( 72,305),(133,369),1
(210,317),(273,384),1
(306,374),(344,420),1
(447,531),(535,632),1
(546,605),(625,707),1
(632,680),(720,790),1
每一行都代表一个目标。每一行的格式如下:
(x1,y1),(x2,y2),a
x1,y1表示检测框左上角点的坐标,x2,y2表示右下角点的坐标。a表示类别序号(1-10分别对应飞机-车辆)。
我们可以通过下面的代码,对标签与图像进行可视化。
【代码】show_data.py
from pathlib import Path
import cv2
import numpy as np
import matplotlib.cm as cmdef generate_colors(n, colormap_name='hsv'):colormap = cm.get_cmap(colormap_name, n)colors = colormap(np.linspace(0, 1, n))colors = (colors[:, :3] * 255).astype(np.uint8) # 将颜色值转换为0到255的整数return colors# 数据集路径
dataset = Path('NWPU VHR-10 dataset')
# 图像路径
images_dir = dataset / 'positive image set'
# 标签路径
ground_truth_dir = dataset / 'ground truth'# 标签框的颜色
colors = generate_colors(10)[:, ::-1].tolist()
# 标签名
names = ['airplane', 'ship', 'storage tank', 'baseball diamond', 'tennis court', 'basketball court', 'ground track field', 'harbor', 'bridge', 'vehicle']for image_path in images_dir.glob('*.jpg'):image = cv2.imread(str(image_path))ground_truth = ground_truth_dir / (image_path.stem + '.txt')# 读取标签labels = []for line in ground_truth.open('r').readlines():line = line.replace('\n', '')if line:labels.append(eval(line))# 遍历所有标签for (x1, y1), (x2, y2), cls in labels:cv2.rectangle(image, (x1, y1), (x2, y2), tuple(colors[cls - 1]), 2)cv2.putText(image, names[cls - 1], (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.75, colors[cls - 1], 2)cv2.imshow('image', image)cv2.waitKey(0)
可视化结果如下:
数据集转换
数据集转换的目的有两个:
- 划分数据集。在有标签的数据中划分出训练集与验证集。
- 转化标签格式。将标签转化为YOLO能够读取的格式。
(1)数据集划分
数据集可划分为训练集与验证集。训练集用于训练模型,验证集用于评估模型。通常来说,训练集与测试集数量的比例为7:3,在训练集数据量较小时,可适当调整为8:2。
(2)转化数据集格式
首先说明YOLO数据集的文件结构:
├─images
│ ├─train
│ └─val
└─labels
├─train
└─val
images目录下分为train目录与val目录,分别存放训练集的图像与验证集的图像;labels目录下同样包含train目录与val目录。我们需要把数据集转换为这样的文件结构。
图像支持jpg、jpeg、png、bmp等常见格式,标签为txt格式,图像与标签按照文件名一一对应,例如001.jpg的标签为001.txt。
txt文件中,,一行表示一个标签。每个检测框检测框需要由5个信息确定,格式要求如下:
c x y w h
c表示类别,x表示检测框中心点的横坐标,y表示检测框中心点的纵坐标,w表示检测框的宽,h表示检测框的高。五个信息之间用空格分隔。
需要注意的是,x、y、w、h都是归一化之后的值。即若图像的宽高为800, 600,中心点的坐标为(400, 300),检测框的宽为80像素,高为60像素,则
接下来,我们可以通过以下代码,完成数据集的转换。
【代码】mkdata.py
from pathlib import Path
import random
import cv2
import shutil# 设置随机数种子
random.seed(0)# 数据集路径
ground_truth_dir = Path('NWPU VHR-10 dataset/ground truth')
# 图像路径
positive_image_set = Path('NWPU VHR-10 dataset/positive image set')# 创建一个data目录,用于保存数据
data_dir = Path('data')
data_dir.mkdir(exist_ok=True)# 创建图像与标签目录
images_dir = data_dir / 'images'
images_dir.mkdir(exist_ok=True)labels_dir = data_dir / 'labels'
labels_dir.mkdir(exist_ok=True)# 创建训练集与验证集目录
for set_name in ['train', 'val']:(images_dir / set_name).mkdir(exist_ok=True)(labels_dir / set_name).mkdir(exist_ok=True)# 所有图像
image_paths = list(positive_image_set.glob('*.jpg'))
# 所有标签
labels = []
for image_path in image_paths:# 读取图像image = cv2.imread(str(image_path))ground_truth = ground_truth_dir / (image_path.stem + '.txt')# 获取图像宽高im_h, im_w = image.shape[:2]# 读取标签lines = []for line in ground_truth.open('r').readlines():line = line.replace('\n', '')if line:(x1, y1), (x2, y2), c = eval(line)# 计算中心点和宽高x = (x1 + x2) / 2y = (y1 + y2) / 2w = abs(x2 - x1)h = abs(y2 - y1)# 归一化x = x / im_wy = y / im_hw = w / im_wh = h / im_h# 把序号变为索引c -= 1lines.append(f'{c} {x} {y} {w} {h}\n')# 保存标签labels.append(lines)# 合并图像路径与标签
data_pairs = list(zip(image_paths, labels))
# 打乱数据
random.shuffle(data_pairs)# 取80%的数据为训练集,剩下的为测试集
train_size = int(len(data_pairs) * 0.8)
train_set = data_pairs[:train_size]
val_set = data_pairs[train_size:]# 遍历训练集与测试集
for set_name, dataset in zip(['train', 'val'], [train_set, val_set]):# 遍历每张图像与标签for image_path, label in dataset:# 复制图像到新的文件夹shutil.copy2(image_path, images_dir / set_name / image_path.name)# 生成标签到新的文件夹with open(labels_dir / set_name / (image_path.stem + '.txt'), 'w') as f:f.writelines(label)
运行代码后,项目的目录结构如下:
通过运行代码,生成了data目录,data目录就是YOLO要求的数据集格式。data目录下有images与labels,images用于存放训练集与验证集的图片,labels用于存放训练集与验证集的标签。
YOLO代码的下载
YOLO代码的调用主要依赖于Ultralytics团队开源的ultralytics库。可以通过下面的链接访问ultralytics官网,官网中提供了使用说明与代码案例。通过使用ultralytics库,仅使用几行代码就可以完成YOLO模型的构建。ultralytics库中支持YOLOv3-YOLOv11算法的训练,除了标准的目标检测外,还支持关键点检测、旋转框检测、实例分割等任务。
Home - Ultralytics YOLO Docshttps://docs.ultralytics.com/https://docs.ultralytics.com/https://docs.ultralytics.com/https://docs.ultralytics.com/ultralytics库可以通过pip命令进行安装,不过为了方便后续对代码的修改,建议下载ultralytics库的源码,源码可以通过下面的链接下载。
GitHub - ultralytics/ultralytics: Ultralytics YOLO11 🚀https://github.com/ultralytics/ultralyticshttps://github.com/ultralytics/ultralyticshttps://github.com/ultralytics/ultralyticshttps://github.com/ultralytics/ultralytics若没有加载Git,可以直接点击Download ZIP下载源码
我们打开下载后的代码只有ultralytics这一个目录是我们需要的,其它文件和目录都不需要,我们可以将ultralytics目录复制到项目目录中。
YOLO的配置
使用ultralytics的核心是“配置”。
通过对数据的配置,能够将整理好的数据集应用于训练;
同时,通过对模型的配置,能够实现使用不同的YOLO算法进行训练。
1.数据集的配置
首先要建立一个yaml文件,我们可以将其命名为dataset.yaml,yaml文件可以放置在ultralytics的同级目录下。yaml文件内容如下:
path: D:/Projects/Python/work/VHR-10/data
train: images/train
val: images/val
test:# Classes
names:0: airplane1: ship2: storage tank3: baseball diamond4: tennis court5: basketball court6: ground track field7: harbor8: bridge9: vehicle
yaml文件分为5个重要的组成部分:
path | 数据集的绝对路径 |
train | 训练集的图像目录 |
val | 验证集的图像目录 |
test | 测试集的图像目录 |
names | 标签索引与标签名 |
path为数据集的绝对路径,程序会自动在path路径下寻找images目录与labels目录。
trian为训练集的图像目录,val为验证集的图像目录,这两个目录都是相对于path的路径。程序同时会自动在labels目录中匹配训练集与验证集的标签。
test是测试集的目录,测试集不是必须的,若没有测试集,此项可以置空。
names是索引与标签的对应。此处的索引对应标签格式中的 c(类别)。
至此,数据集的配置完成。
2.模型的配置
ultralytics支持YOLOv3至YOLO11的大多数模型,需要注意的是,YOLOv4与YOLOv7虽然给出了介绍,但实际上并不支持模型的训练。此外,YOLO的第11个版本的命名。并不是“YOLOv11”,而是去掉中间的“v”,命名为YOLO11。
第一步,选择适合的模型并下载预训练权重。
我们以YOLO11为例,点击YOLO11的详情页,向下翻可以找到这样一个表格。
表格记录了YOLO11 5种规格模型的具体信息,模型规模从小到大依次为:n、s、m、l、s。
表格种还提供了模型在COCO数据集中的验证集指标(mAP,越高越好),以及推理时间、参数量、计算量等。我们可以选择合适的模型进行训练,为了实现遥感目标检测,我们使用规格最小的YOLO11n作为演示。
点击YOLO11n的蓝色模型名,即可下载模型的预训练权重,使用预训练权重有助于提升检测精度与收敛速度。
我们可以将下载好的预训练权重放置在ultralytics的同级目录下。
第二步,设置训练代码。
在ultralytics的同级目录下,创建文件train.py。此时,代码目录如下:
train.py中,只需要四行代码,就可以完成YOLO模型的训练。代码如下:
【代码】train.py
from ultralytics import YOLOif __name__ == '__main__':yolo = YOLO('yolo11n.yaml')yolo.train(data='dataset.yaml', epochs=100, batch=3)
yolo11的配置文件在ultralytics/cfg/models/11/yolo11.yaml中,但我们输入的是yolo11n.yaml,系统将会自动在yolo11.yaml解析规格为n的配置,加载YOLO11n模型。同理,若想使用YOLO11s模型,则指定yolo = YOLO('yolo11s.yaml')即可。
使用此代码进行训练,将自动加载先前下载的yolo11n.pt作为预训练权重,若更改模型,还需要下载其它规格的预训练权重。
YOLO11模型的训练
运行train.py文件,即可开始训练模型。
出现如下界面后,即为训练成功。
等待模型训练完成,得到结果如下:
从图中我们可以看出,最终所有类别的平均mAP50为0.757,mAP50-95为0.422。
我们也可以看到其它类别的指标,mAP50最高的为地面田径场(ground track field),mAP最低的为篮球场(basketball court)。
训练时,模型会自动生成一个runs目录,我们训练的结果将会保存在runs目录中。
runs目录下会生成一个detect目录与一个mlflow目录,mlflow目录是利用mlflow平台进行训练过程的可视化,我们暂时先不关注这个目录。
detect目录内保存了检测任务的所有训练结果,第一次训练命名为“train”,第二次训练命名为“train2”,以此类推。我们需要找到最后一次训练的目录,查看结果。也可以在训练时控制台的输出中,找到相应的结果目录。
其中,labels.jpg是对标签的统计。
results.png是训练过程中各个指标的记录。
val_batch*_labels.jpg与val_batch*_pred.jpg分别表示验证集的某个batch最终的真实标签与预测结果。
真实标签:
预测结果:
我们可以发现,在245.jpg中,有三个网球场没有识别出来,且误识别了一个飞机;
574.jpg中,误识别了一些飞机;
547.jpg中,桥的识别出现了重叠的情况;
等等。
我们可以根据预测的情况来分析模型的状况,通过观察上面的结果,我们发现模型还有很大的改进空间。
其它版本YOLO的训练
接下来,我们尝试通过YOLOv5算法来实现。
首先打开YOLOv5模型详情页,下载yolov5n模型的权重,并将下载后的权重放置在train.py的同级目录下。
模型修改如下:
【代码】train.py
from ultralytics import YOLOif __name__ == '__main__':# yolo = YOLO('yolo11n.yaml')yolo = YOLO('yolov5n.yaml')yolo.train(data='dataset.yaml', epochs=100, close_mosaic=0, batch=3)
仅需要将yolo11n.yaml改为yolov5n.yaml,就能实现算法的替换。YOLOv5训练结果如下:
最终的mAP50为0.751,mAP50-95为0.415,略逊于YOLO11。
最后推荐一本书,这本书内集成了YOLO算法应用在内的基于MATLAB实现的将近30个计算机视觉案例,涵盖了计算机视觉的许多实际应用场景,包括图像去雾、答题卡识别、医学影像分割、图像检索等。也可尝试通过PyTorch实现此书内的案例。