当前位置: 首页 > news >正文

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 多平台发布

相关文章:

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

1 目标检测是计算机视觉领域中的一项重要任务,它的目标是在图像或视频中检测出物体的位置和类别。YOLO(You Only Look Once)是一系列经典的目标检测算法,最初由Joseph Redmon等人于2016年提出。YOLO算法具有快速、简单、端到端的特…...

stable-diffusion-electron-clickstart 支持windows AMD显卡

前言 使用vue3 vite electron element-plus构建,正好学习下electrongithub stable-diffusion “画境导航者” 启动器 简介 stable-diffusion “画境导航者” 启动器支持功能 一键启动打开文件夹(tmp、txt2img-images)等模型所在文件夹&…...

ES进程除了kill之外,有什么优雅关闭的方式吗?

问题 Linux环境中,Elasticsearch 8的进程除了kill之外,有什么优雅关闭的方式吗? 具体实施方式 在Linux环境中,Elasticsearch(ES)进程可以通过多种方式实现优雅关闭,这种方式允许它完成必要的…...

院子摄像头的监控

院子摄像头的监控和禁止区域入侵检测相比,多了2个功能:1)如果检测到有人入侵,则把截图保存起来,2)如果检测到有人入侵,则向数据库插入一条事件数据。 打开checkingfence.py,添加如下…...

SpringBoot3使用响应Result类返回的响应状态码为406

Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation] 解决方法:Result类上加上Data注解...

基础:TCP四次挥手做了什么,为什么要挥手?

1. TCP 四次挥手在做些什么 1. 第一次挥手 : 1)挥手作用:主机1发送指令告诉主机2,我没有数据发送给你了。 2)数据处理:主机1(可以是客户端,也可以是服务端)&#xff0c…...

Android Studio实现内容丰富的安卓校园二手交易平台(带聊天功能)

获取源码请点击文章末尾QQ名片联系,源码不免费,尊重创作,尊重劳动 项目编号083 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端: 1.注册登录 2.查看二手商品列表 3.发布二手商品 4.商品详情 5.聊天功能…...

第十一届蓝桥杯省赛第一场真题

2065. 整除序列 - AcWing题库 #include <bits/stdc.h> using namespace std; #define int long long//记得开long long void solve(){int n;cin>>n;while(n){cout<<n<< ;n/2;} } signed main(){int t1;while(t--)solve();return 0; } 2066. 解码 - …...

设计模式 模板方法模式

01.如果接到一个任务&#xff0c;要求设计不同型号的悍马车 02.设计一个悍马车的抽象类&#xff08;模具&#xff0c;车模&#xff09; public abstract class HummerModel {/** 首先&#xff0c;这个模型要能够被发动起来&#xff0c;别管是手摇发动&#xff0c;还是电力发动…...

【STM32嵌入式系统设计与开发】——6矩阵按键应用(4x4)

这里写目录标题 一、任务描述二、任务实施1、SingleKey工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#xff08;2&#xff09;LED IO初始化函数(LED_Init())&#xff08;3&#xff09;开发板矩阵键盘IO初始化&#xff08;ExpKeyBordInit()&#xff09;&…...

乐优商城(九)数据同步RabbitMQ

1. 项目问题分析 现在项目中有三个独立的微服务&#xff1a; 商品微服务&#xff1a;原始数据保存在 MySQL 中&#xff0c;从 MySQL 中增删改查商品数据。搜索微服务&#xff1a;原始数据保存在 ES 的索引库中&#xff0c;从 ES 中查询商品数据。商品详情微服务&#xff1a;做…...

XSS-labs详解

xss-labs下载地址https://github.com/do0dl3/xss-labs 进入靶场点击图片&#xff0c;开始我们的XSS之旅&#xff01; Less-1 查看源码 代码从 URL 的 GET 参数中取得 "name" 的值&#xff0c;然后输出一个居中的标题&#xff0c;内容是 "欢迎用户" 后面…...

设计模式——模板方法模式封装.net Core读取不同类型的文件

1、模板方法模式 模板方法模式&#xff1a;定义一个操作中的算法骨架&#xff0c;而将一些步骤延迟到子类中&#xff0c;模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 特点&#xff1a;通过把不变的行为搬移到超类&#xff0c;去除子类中重复的代…...

[思考记录]技术欠账

最近对某开发项目做回顾梳理&#xff0c;除了进一步思考整理相关概念和问题外&#xff0c;一个重要的任务就是清理“技术欠账”。 这个“技术欠账”是指在这个项目的初期&#xff0c;会有意无意偏向快速实现&#xff0c;想先做出来、用起来&#xff0c;进而在实现过程中做出…...

React - 实现菜单栏滚动

简介 本文将会基于react实现滚动菜单栏功能。 技术实现 实现效果 点击菜单&#xff0c;内容区域会自动滚动到对应卡片。内容区域滑动&#xff0c;指定菜单栏会被选中。 ScrollMenu.js import {useRef, useState} from "react"; import ./ScrollMenu.css;export co…...

线性筛选(欧拉筛选)-洛谷P3383

#include <bits/stdc.h> using namespace std; int main() {std::ios::sync_with_stdio(false); cin.tie(nullptr); //为了加速int n, q;cin >> n >> q; vector<int>num(n 1); //定义数字表vector<int>prime; //定义素数表数组num[1] …...

企业微信可以更换公司主体吗?

企业微信变更主体有什么作用&#xff1f;当我们的企业因为各种原因需要注销或已经注销&#xff0c;或者运营变更等情况&#xff0c;企业微信无法继续使用原主体继续使用时&#xff0c;可以申请企业主体变更&#xff0c;变更为新的主体。企业微信变更主体的条件有哪些&#xff1…...

Qt教程 — 3.6 深入了解Qt 控件:Display Widgets部件(2)

目录 1 Display Widgets简介 2 如何使用Display Widgets部件 2.1 QTextBrowser组件-简单的文本浏览器 ​2.2 QGraphicsView组件-简单的图像浏览器 Display Widgets将分为两篇文章介绍 文章1&#xff08;Qt教程 — 3.5 深入了解Qt 控件&#xff1a;Display Widgets部件-CSDN…...

Golang案例开发之gopacket抓包三次握手四次分手(3)

文章目录 前言一、理论知识三次握手四次分手二、代码实践1.模拟客户端和服务器端2.三次握手代码3.四次分手代码验证代码完整代码总结前言 TCP通讯的三次握手和四次分手,有很多文章都在介绍了,当我们了解了gopacket这个工具的时候,我们当然是用代码实践一下,我们的理论。本…...

如何减少pdf的文件大小?pdf压缩工具介绍

文件发不出去&#xff0c;有时就会耽误工作进度&#xff0c;文件太大无法发送&#xff0c;这应该是大家在发送PDF时&#xff0c;常常会碰到的问题吧&#xff0c;那么PDF文档压缩大小怎么做呢&#xff1f;因此我们需要对pdf压缩后再发送&#xff0c;那么有没有好用的pdf压缩工具…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...