基于Yolov8的野外烟雾检测(1)

目录

 1.Yolov8介绍

2.野外火灾烟雾数据集介绍

2.1数据集划分

1.2 通过voc_label.py得到适合yolov8需要的txt

2.3生成内容如下

3.训练结果分析

4.系列篇


 1.Yolov8介绍

         Ultralytics YOLOv8是Ultralytics公司开发的YOLO目标检测和图像分割模型的最新版本。YOLOv8是一种尖端的、最先进的(SOTA)模型,它建立在先前YOLO成功基础上,并引入了新功能和改进,以进一步提升性能和灵活性。它可以在大型数据集上进行训练,并且能够在各种硬件平台上运行,从CPU到GPU。

具体改进如下:

  1. Backbone:使用的依旧是CSP的思想,不过YOLOv5中的C3模块被替换成了C2f模块,实现了进一步的轻量化,同时YOLOv8依旧使用了YOLOv5等架构中使用的SPPF模块;

  2. PAN-FPN:毫无疑问YOLOv8依旧使用了PAN的思想,不过通过对比YOLOv5与YOLOv8的结构图可以看到,YOLOv8将YOLOv5中PAN-FPN上采样阶段中的卷积结构删除了,同时也将C3模块替换为了C2f模块;

  3. Decoupled-Head:是不是嗅到了不一样的味道?是的,YOLOv8走向了Decoupled-Head;

  4. Anchor-FreeYOLOv8抛弃了以往的Anchor-Base,使用了Anchor-Free的思想;

  5. 损失函数YOLOv8使用VFL Loss作为分类损失,使用DFL Loss+CIOU Loss作为分类损失;

  6. 样本匹配YOLOv8抛弃了以往的IOU匹配或者单边比例的分配方式,而是使用了Task-Aligned Assigner匹配方式

框架图提供见链接:Brief summary of YOLOv8 model structure · Issue #189 · ultralytics/ultralytics · GitHub

2.野外火灾烟雾数据集介绍

数据集大小737张,train:val:test 随机分配为7:2:1,类别:smoke

2.1数据集划分

通过split_train_val.py得到trainval.txt、val.txt、test.txt  

# coding:utf-8

import os
import random
import argparse

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

trainval_percent = 0.9
train_percent = 0.7
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)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)

file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w')

for i in list_index:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        file_trainval.write(name)
        if i in train:
            file_train.write(name)
        else:
            file_val.write(name)
    else:
        file_test.write(name)

file_trainval.close()
file_train.close()
file_val.close()
file_test.close()

1.2 通过voc_label.py得到适合yolov8需要的txt

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val']
classes = ["smoke"]   # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)

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):
    in_file = open('Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('labels/%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 or int(difficult) == 1:
            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')

wd = getcwd()
for image_set in sets:
    if not os.path.exists('labels/'):
        os.makedirs('labels/')
    image_ids = open('ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    list_file = open('%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write(abs_path + '/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val']
classes = ["smoke"]   # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)

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):
    in_file = open('Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('labels/%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 or int(difficult) == 1:
            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')

wd = getcwd()
for image_set in sets:
    if not os.path.exists('labels/'):
        os.makedirs('labels/')
    image_ids = open('ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
    list_file = open('%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write(abs_path + '/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

2.3生成内容如下

3.训练结果分析

训练结果如下:

mAP@0.5 0.839

YOLOv8n summary (fused): 168 layers, 3005843 parameters, 0 gradients, 8.1 GFLOPs
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 4/4 [00:06<00:00,  1.55s/it]
                   all        199        177      0.749      0.859      0.839      0.469

4.系列篇

1)基于Yolov8的野外烟雾检测

2)基于Yolov8的野外烟雾检测(2):多维协作注意模块MCA| 2023.9最新发布

3)基于Yolov8的野外烟雾检测(3):动态蛇形卷积,实现暴力涨点 | ICCV2023

4)基于Yolov8的野外烟雾检测(4):通道优先卷积注意力(CPCA) | 中科院2023最新发表 

 


http://www.niftyadmin.cn/n/5037303.html

相关文章

惯性动捕+数据手套,让“虚拟”触手可及

当今&#xff0c;虚拟现实技术已经从科幻电影走进现实生活。在数字化时代&#xff0c;惯性动作捕捉系统与数据手套的结合使用&#xff0c;带给我们全新的虚拟互动体验&#xff0c;使虚拟世界更能够“触手可及”。 01 惯性动作捕捉系统 FOHEART MAGIC是一款高性能的惯性动作捕…

ES6 什么是模板字符串?

模板字符串是一种在编程中用于创建字符串的特殊语法形式&#xff0c;通常用于动态生成包含变量或表达式的文本。它们在许多编程语言中都有类似的实现&#xff0c;但语法可能会有所不同。 在JavaScript中&#xff0c;模板字符串是由反引号 (backtick) 包围的字符串&#xff0c…

Linux查看程序和动态库依赖的动态库

一. 前言 在一些时候&#xff0c;我们需要知道一个程序或者动态库所依赖的动态库有哪些。比如&#xff0c;当我们运行一个程序的时候&#xff0c;发现可能会报错&#xff0c;提示找不到某个符号&#xff0c;这时我们就需要知道程序依赖了什么库&#xff0c;从而添加对应需要的动…

[Vue] 绑定下拉菜单

写在前面 同学们&#xff0c;今天的天气很是不错&#xff0c;我们之前进行了复选框的绑定&#xff0c;这次来看看下拉菜单的绑定吧&#xff0c;因为要赶这个创作进度&#xff0c;真的只有再水一篇文章了。大家就当是饭后甜点看看就行。 苏子云 荷尽已无擎雨盖&#xff0c;菊残…

助力工业智能化升级 复合移动机器人生态圈在沪启动

9月19日&#xff0c;由移动机器人&#xff08;AGV/AMR&#xff09;产业联盟组织&#xff0c;深圳优艾智合机器人科技有限公司&#xff08;以下简称“优艾智合”&#xff09;牵头&#xff0c;工业机器人产业上下游30家代表企业共同组成的复合移动机器人生态圈在上海国家会展中心…

代码随想录day57|647. 回文子串516. 最长回文子序列

647. 回文子串 class Solution:def countSubstrings(self, s: str) -> int:#dp[i][j]表示从i 到j 的回文子串个数dp [[False] * len(s) for _ in range(len(s))]result0for i in range(len(s)-1,-1,-1):for j in range(i,len(s)):if s[i] s[j]:if j -i <1:dp[i][j]Tru…

ffmpeg抠图

1.不用png&#xff0c;用AVFrame 2.合流 3.图片抠图透明 (1.)mp4扣yuv图&#xff0c;(2)用1.把一张yuv标记为透明然后av_hwframe_transfer_data到GPU (3)用抠图算法函数对yuv进行处理 (4) qsv的h264_qsv只支持nv12和qsv&#xff0c;但qsv本身并不限制像素格式&#xff0c;比如在…

讨论问题--数据类型、数组、传值/址API函数等

前言 数据类型是编程语言中用于表示数据的分类。常见的数据类型包括整数、浮点数、字符串、布尔值等。数据类型决定了变量能存储的值的种类和范围。 数组是一种存储多个相同类型数据的数据结构。它通过索引来访问并操作其中的元素。数组在内存中是连续存储的&#xff0c;可以…