yolov6实现遥感影像目标识别|以DIOR数据集为例

alt 1

目标检测是计算机视觉领域中的一项重要任务,它的目标是在图像或视频中检测出物体的位置和类别。YOLO(You Only Look Once)是一系列经典的目标检测算法,最初由Joseph Redmon等人于2016年提出。YOLO算法具有快速、简单、端到端的特点,并且在速度和准确率上取得了很好的平衡,因此受到了广泛的关注和应用。

YOLO系列算法的核心思想是将目标检测问题转化为一个回归问题。它将整个图像分成一个固定大小的网格,每个网格负责检测该网格内的物体。YOLO算法在每个网格上预测多个边界框(bounding box),以及每个边界框所属的物体类别以及置信度分数。

YOLO算法系列有多个版本,包括YOLOv1、YOLOv2(也称为YOLO9000)、YOLOv3和YOLOv4等。每个版本都在YOLO的基础上进行了改进,提高了检测精度、速度和通用性。

「今天我们将实现YOLO V6的遥感影像目标检测。」

YOLO V6

YOLOv6 是美团视觉智能部研发的一款目标检测框架,致力于工业应用。本框架同时专注于检测的精度和推理效率,在工业界常用的尺寸模型中:YOLOv6-nano 在 COCO 上精度可达 35.0% AP,在 T4 上推理速度可达 1242 FPS;YOLOv6-s 在 COCO 上精度可达 43.1% AP,在 T4 上推理速度可达 520 FPS。在部署方面,YOLOv6 支持 GPU(TensorRT)、CPU(OPENVINO)、ARM(MNN、TNN、NCNN)等不同平台的部署,极大地简化工程部署时的适配工作。目前,项目已开源至 Github。

解决的问题:

RepVGG提出的结构重参数化方法表现良好,但在此之前没有检测模型使用。作者认为RepVGG的block缩放不合理,小模型和大模型没必要保持相似网络结构;小模型使用单路径架构,大模型就不适合在单路径上堆参数量。

使用重参数化的方法后,检测器的量化也需要重新考虑,否则因为训练和推理时的结构不同,性能可能会退化。

前期工作很少关注部署。前期工作中,推理是在V100等高配机器完成的,但实际使用时往往用T4等低功耗推理gpu,作者更关注后者的性能。

针对网络结构的变化,重新考虑标签分配和损失函数。

对于部署,可以调整训练策略,在不增加推理成本的情况下提升性能,如使用知识蒸馏。

具体实现:

网络设计

在one-satge的目标检测网络中,Backbone决定了表征能力,也很大程度上影响了参数量和推理效率;Neck主要作用是聚合高低层次的语义信息;Head由几个卷积层组成,负责预测最终结果。

考虑到硬件推理的因素,YOLOv6提出两个可缩放的可重参数化的Backbone和Neck来适应不同大小的模型,还提出一个使用混合通道策略的高效解耦头,总体网络结构如下:

alt

BackBone

在分类性能上,多分支网络相比单分支表现更好,但随并行性降低,其推理速度减慢。RepVGG的结构重参数化方式,采用多分支训练和单分支推理,达到了较好的精度-速度权衡。 alt YOLOv6设计了可重参数化的Backbone并命名为EfficientRep。对于小模型,backbone的主要组成部分是训练阶段的 RepBlock,如图2(a)所示。在推理阶段,RepBlock转换为3×3卷积层+ReLU激活函数的堆叠(记为 RepConv),如图2(b)所示。因为3*3卷积在CPU和GPU上优化和计算密度都更好,所以在增强表征能力的同时,可以有效利用计算资源同时增加推理速度。 然而随模型容量增加,单路径模型的计算代价和参数量呈指数级提升,所以改用CSPStackRep Block作为中大型网络的Backbone,如图2(c)所示。CSPStackRep Block由三个1×1卷积和两个带残差连接的RepVGG block(训练使用)或RepConv(推理使用)组成的模块堆叠。可以在不增加计算成本的前提下提升性能,做到准确率和速度的权衡。

Neck

集成多尺度的特征是检测模型常用且有效的手段,YOLOv6也不例外,在PAN的基础上,把CSPBlock替换为RepBlock(小模型使用)或CSPStackRep Block(大模型使用),并调整宽度和深度,将YOLOv6的颈部命名为Rep-PAN。

Head

YOLOv5的检测头在分类和回归上共享参数,而FCOS和YOLOX将两个分支解耦,在每个分支中引入两个额外3×3卷积层提高性能。YOLOv6则采用混合通道策略构建高效解耦头,即中间3*3卷积只使用一个,Head的宽度由Backbone和Neck的宽度因子共同缩放,从而进一步降低了计算成本和延迟。此外,YOLOv6使用基于锚点的Anchor free方式,预测锚点到边界框四周的距离。

源码

源码地址;https://github.com/meituan/YOLOv6

安装

git clone https://github.com/meituan/YOLOv6
cd YOLOv6
pip install -r requirements.txt

DIOR数据集

「DIOR」由23463张最优遥感图像和190288个目标实例组成,这些目标实例用轴向对齐的边界框手动标记,由192472个轴对齐的目标边界框注释组成。数据集中图像大小为800×800像素,空间分辨率为0.5m ~ 30m。该数据集分为训练验证集(11725张图像)和测试集(11738张图像)。 「DIOR」是一个用于光学遥感图像目标检测的大规模基准数据集。涵盖20个对象类。这20个对象类是飞机、机场、棒球场、篮球场、桥梁、烟囱、水坝、高速公路服务区、高速公路收费站、港口、高尔夫球场、地面田径场、天桥、船舶、体育场、储罐、网球场、火车站、车辆和风磨。 论文地址:Object Detection in Optical Remote Sensing Images: A Survey and A New Benchmark

数据集处理

由于dior数据集是voc格式,所以需要将其转换为yolo格式。可以参照yolo v6中给出的voc2yolo.py。

也可以参照以下的方法。

新建一个文件夹JPEGImages,将JPEGImages-test和PEGImages-trainval里的图片都放进JPEGImages里面。 代码参考链接:https://blog.csdn.net/weixin_43365477/article/details/135622835

# coding:utf-8

import os
import random
import argparse

import xml.etree.ElementTree as ET
from os import getcwd
from shutil import copyfile


parser = argparse.ArgumentParser()
#xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
parser.add_argument('--xml_path', default='DIOR/Annotations', type=str, help='input xml label path')
#数据集的划分,地址选择自己数据下的ImageSets/Main

opt = parser.parse_args()

sets = ['train''val''test']
classes = ['airplane''airport''baseballfield''basketballcourt''bridge''chimney''dam',
              'Expressway-Service-area''Expressway-toll-station''golffield''groundtrackfield''harbor',
              'overpass''ship''stadium''storagetank''tenniscourt''trainstation''vehicle''windmill']

abs_path = os.getcwd()
print(abs_path)


# if not os.path.exists('/DIOR'):
#     os.makedirs('DIOR')

if not os.path.exists('DIOR_dataset/labels/'):
    os.makedirs('DIOR_dataset/labels/')
if not os.path.exists('DIOR_dataset/labels/train'):
    os.makedirs('DIOR_dataset/labels/train')
if not os.path.exists('DIOR_dataset_yolo/labels/test'):
    os.makedirs('DIOR_dataset/labels/test')
if not os.path.exists('DIOR_dataset_yolo/labels/val'):
    os.makedirs('DIOR_dataset/labels/val')


if not os.path.exists('DIOR_dataset/images/'):
    os.makedirs('DIOR_dataset/images/')
if not os.path.exists('DIOR_dataset/images/train'):
    os.makedirs('DIOR_dataset/images/train')
if not os.path.exists('DIOR_dataset/images/test'):
    os.makedirs('DIOR_dataset/images/test')
if not os.path.exists('DIOR_dataset/images/val'):
    os.makedirs('DIOR_dataset/images/val')


def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    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, path):
#输入输出文件夹,根据实际情况进行修改
    in_file = open('DIOR/Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('DIOR_dataset/labels/' + path + '/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        #difficult = obj.find('difficult').text
        #difficult = obj.find('Difficult').text
        cls = obj.find('name').text
        if cls not in classes:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')



train_percent = 0.6
test_percent = 0.2
val_percent = 0.2

xmlfilepath = opt.xml_path
# txtsavepath = opt.txt_path
total_xml = os.listdir(xmlfilepath)
# if not os.path.exists(txtsavepath):
#     os.makedirs(txtsavepath)

num = len(total_xml)
list_index = range(num)
list_index = list(list_index)
random.shuffle(list_index)


train_nums = list_index[:int(num * train_percent)]
test_nums = list_index[int(num * train_percent): int(num * test_percent)+int(num * train_percent)]
val_nums = list_index[int(num * test_percent)+int(num * train_percent):]



for i in list_index:
    name = total_xml[i][:-4]
    if i in train_nums:
        convert_annotation(name, 'train')   # lables
        image_origin_path = 'DIOR/JPEGImages/' + name + '.jpg'
        image_target_path = 'DIOR_dataset/images/train/' + name + '.jpg'
        copyfile(image_origin_path, image_target_path)

    if i in test_nums:
        convert_annotation(name, 'test')   # lables
        image_origin_path = 'DIOR/JPEGImages/' + name + '.jpg'
        image_target_path = 'DIOR_dataset/images/test/' + name + '.jpg'
        copyfile(image_origin_path, image_target_path)

    if i in val_nums:
        convert_annotation(name, 'val')   # lables
        image_origin_path = 'DIOR/JPEGImages/' + name + '.jpg'
        image_target_path = 'DIOR_dataset/images/val/' + name + '.jpg'
        copyfile(image_origin_path, image_target_path)

最终会生成yolo格式的数据集,且按训练集、验证集、测试集划分开。最终数据集形式如下 alt

YOLO V6训练DIOR

YOLO V6的操作文档可以看这里:https://yolov6-docs.readthedocs.io/zh-cn/latest/ 我们针对我们制作的DIOR数据集,来修改参数。

修改dataset.yaml

找到源代码中data/dataset.yaml。

# Please insure that your custom_dataset are put in same parent dir with YOLOv6_DIR
# 放入刚处理的DIOR数据集路径
train: .\DIOR_dataset\images\train # train images
val: .\DIOR_dataset\images\val # val images
test: .\DIOR_dataset\images\test # test images (optional)

# whether it is coco dataset, only coco dataset should be set to True.
is_coco: False

# Classes,类别名
nc: 20  # number of classes
names: ['airplane''airport''baseballfield''basketballcourt''bridge''chimney''dam',
              'Expressway-Service-area''Expressway-toll-station''golffield''groundtrackfield''harbor',
              'overpass''ship''stadium''storagetank''tenniscourt''trainstation''vehicle''windmill']  # class names

修改train.py

找到源代码中tools/train.py。 修改img-size为800,其他选项根据注释自行修改。

训练

运行train.py

测试

训练结束后,运行tools/eval.py。即可验证精度(注意weights改成训练结果路径),img-size为800。

输出结果

运行tools/infer.py source为test图片路径,其它参数根据注释选择性修改。 部分测试结果如下。 alt alt alt alt

总结

今天的分享就到这里,感兴趣的可以自行下载数据集与源代码试试。

往期精彩

SENet实现遥感影像场景分类
SENet实现遥感影像场景分类
DFANet|实现遥感影像道路提取
DFANet|实现遥感影像道路提取
基于topformer实现遥感影像道路提取
基于topformer实现遥感影像道路提取
segformer实现多分类遥感影像语义分割
segformer实现多分类遥感影像语义分割
pyqt5实现语义分割GUI界面工具
pyqt5实现语义分割GUI界面工具

本文由 mdnice 多平台发布

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习之---统计】统计学基础概念

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 统计学基础 1. 频率派 频率学派(传统学派)认为样本信息来自总体,通过对样本信息的研究可以合理地推断和估计总体信息…

深入理解MySQL中的JOIN算法

码到三十五 : 个人主页 心中有诗画,指尖舞代码,目光览世界,步履越千山,人间尽值得 ! 目录 一、引言二、嵌套循环连接(Nested-Loop Join)2.1 工作原理2.2 性能考虑2.3 优化策略 三、块嵌套循环…

如何在iOS系统抓取log

前言:因为作者目前工作领域和苹果智能家居有关,然后发现一些bug其实是apple sdk原生code的问题,所以需要给apple提radar单,就需要抓ios端Log充当证据给apple看,其实ios抓log非常简单,大家感兴趣可以学习下哦…

谈谈synchronized关键字

synchronized是什么? synchronized为同步之意,可保证在同一时刻,被它修饰的方法或代码块只能有一个线程执行,它的使用解决了并发多线程中的三大问题:原子性、可见性、顺序性。 有的书籍中可能会看到说synchronized是…

用vscode调试cpp程序相关操作记录

需要在服务器上用vscode调试cpp程序,写此记录launch.json配置和相关步骤错误导致的问题 1.在需要运行程序的服务器上安装C/C Extension Pack(之前只在本地装了),可以支持调试C/C应用程序(设置断点,单步执行&#xff0c…

【计算机视觉】Gaussian Splatting源码解读补充(二)

第一部分 本文是对学习笔记之——3D Gaussian Splatting源码解读的补充,并订正了一些错误。 目录 三、相机相关scene/cameras.py:class Camera 四、前向传播(渲染):submodules/diff-gaussian-rasterization/cuda_rast…

【java数据结构】基于java提供的ArrayList实现的扑克牌游戏-(附源码~)

【Java数据结构】基于java泛型实现的二维数组完成三人扑克游戏 基本框架的实现创建一副牌如何进行洗牌:每个人抓的牌放到哪里: 源码具体实现cardcardsTest 个人简介:努力学编程 每日鸡汤:stay foolish,stay hungry-史蒂芬.乔布斯斯…

springboot+vue 的图书个性化推荐系统的设计与实现

图书个性化推荐系统的主要使用者分为管理员和学生,实现功能包括管理员:首页、个人中心、学生管理、图书分类管理、图书信息管理、图书预约管理、退换图书管理、管理员管理、留言板管理、系统管理,学生:首页、个人中心、图书预约管…

适用于 Windows PC 的 6 款最佳照片恢复软件

您想向您的朋友展示您上个月访问迈阿密海滩的照片。可惜!您的 Windows 计算机中不再有照片文件夹。不仅是这个文件夹,您还发现您的许多重要和有趣时刻的照片都丢失了!这意味着您丢失了许多家庭成员、可爱宝宝的珍贵照片或毕业典礼等难忘活动的…

利用Base64加密算法将数据加密解密

1. Base64加密算法 Base64准确来说并不像是一种加密算法,而更像是一种编码标准。 我们知道现在最为流行的编码标准就是ASCLL,它用八个二进制位(一个char的大小)表示了127个字符,任何二进制序列都可以用这127个字符表…

chap验证实验

一、添加接口 在每个路由器里添加2SA接口 二、配IP 进入serial接口配置IP R1: R2: ppp mp Mp-group 0/0/0 R3: 查看: 三、aaa认证,chap验证 创建一个新用户: R2进入3/0/0接口: R1进入3/0/0接口&a…

制作一个RISC-V的操作系统六-bootstrap program(risv 引导程序)

文章目录 硬件基本概念qemu-virt地址映射系统引导CSR![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/86461c434e7f4b1b982afba7fad0256c.png)machine模式下的csr对应的csr指令csrrwcsrrs mhartid引导程序做的事情判断当前hart是不是第一个hart初始化栈跳转到c语言的…

【Android开发】【创建Activity,Activity之间的切换/消息传递】【java】

一、第一个Activity 1.1 创建一个空Activity 1.2 创建一个布局 知识点 在XML中引用一个id:id/id_name 在XML中定义一个id:id/id_name 右键错误,点击Show Quick-Fixes,再点击弹出的Suppress:Add........,错误会被自动修…

详细分析PyAutoGUI中的locate函数(附Demo)

目录 前言1. 基本知识2. 源代码分析3. Demo 前言 起因是实战中locate对个别定位会有偏差,导致一直识别错误 相应的基本知识推荐阅读:详细分析Python中的Pyautogui库(附Demo) 1. 基本知识 pyautogui.locate()函数用于在屏幕上定…

DBO优化朴素贝叶斯分类预测(matlab代码)

DBO-朴素贝叶斯分类预测matlab代码 蜣螂优化算法(Dung Beetle Optimizer, DBO)是一种新型的群智能优化算法,在2022年底提出,主要是受蜣螂的的滚球、跳舞、觅食、偷窃和繁殖行为的启发。 数据为Excel分类数据集数据。 数据集划分为训练集、验证集、测试…

YOLO-v8-seg实例分割使用

最近需要实例分割完成一些任务,一直用的SAM(segment anything)速度慢,找一个轻量分割模型。 1. YOLO-v8-seg使用 git clone https://github.com/ultralytics/ultralytics.git cd ultralytics vim run.py from ultralytics import YOLO# L…

鸿蒙一次开发,多端部署(十三)功能开发的一多能力介绍

应用开发至少包含两部分工作: UI页面开发和底层功能开发(部分需要联网的应用还会涉及服务端开发)。前面章节介绍了如何解决页面适配的问题,本章节主要介绍应用如何解决设备系统能力差异的兼容问题。 系统能力 系统能力&#xff…

RK3568驱动指南|第十三篇 输入子系统-第143章 多对多的匹配关系分析

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

有哪些强大好用的AI表格数据处理工具或者 AI Excel工具?

在繁忙的工作和生活中,处理大量的表格数据往往令人感到头疼。面对一列列数字、一行行文字,我们需要花费大量的时间和精力去整理、核对。然而,随着科技的飞速发展,人工智能(AI)技术正逐渐改变这一现状。 如…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…