睿智的目标检测64——目标检测中的MixUp数据增强方法

news2024/5/18 18:11:19

睿智的目标检测64——目标检测中的MixUp数据增强方法

  • 学习前言
  • 代码下载
  • 什么是MixUp数据增强方法
  • 实现思路
  • 全部代码
    • 1、数据增强与MixUp
    • 2、调用代码

学习前言

哈哈哈!我再来一次数据增强!
在这里插入图片描述

代码下载

https://github.com/bubbliiiing/object-detection-augmentation

什么是MixUp数据增强方法

MixUp数据增强方法在最新的几个Yolo算法中得到了广泛的应用,特别在YoloX中,s、m、l、x四个型号的网络都使用了MixUp数据增强。nano和tiny由于模型的拟合能力一般没有使用MixUp,但也说明了MixUp具有强大的数据增强能力。

MixUp的思路较为简单,主要是将两张图像按比例进行混合,如图所示:
在这里插入图片描述
图片混合完成后,原来两幅图片的真实框此时也位于一幅图像上。

实现思路

1、每次读取两张的图片。
在这里插入图片描述
在这里插入图片描述
2、分别对两张图片进行翻转、缩放、色域变化等数据增强。在这里插入图片描述
在这里插入图片描述
3、将二者的真实框堆叠到一起。
在这里插入图片描述

全部代码

1、数据增强与MixUp

该部分为普通数据增强与MixUp的代码

import cv2
import numpy as np
from PIL import Image, ImageDraw


def rand(a=0, b=1):
    return np.random.rand()*(b-a) + a

def get_random_data(annotation_line, input_shape, jitter=.3, hue=.1, sat=0.7, val=0.4, random=True):
    line    = annotation_line.split()
    #------------------------------#
    #   读取图像并转换成RGB图像
    #------------------------------#
    image   = Image.open(line[0])
    image   = image.convert('RGB')

    #------------------------------#
    #   获得图像的高宽与目标高宽
    #------------------------------#
    iw, ih  = image.size
    h, w    = input_shape
    #------------------------------#
    #   获得预测框
    #------------------------------#
    box     = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]])

    if not random:
        scale = min(w/iw, h/ih)
        nw = int(iw*scale)
        nh = int(ih*scale)
        dx = (w-nw)//2
        dy = (h-nh)//2

        #---------------------------------#
        #   将图像多余的部分加上灰条
        #---------------------------------#
        image       = image.resize((nw,nh), Image.BICUBIC)
        new_image   = Image.new('RGB', (w,h), (128,128,128))
        new_image.paste(image, (dx, dy))
        image_data  = np.array(new_image, np.float32)

        #---------------------------------#
        #   对真实框进行调整
        #---------------------------------#
        if len(box)>0:
            np.random.shuffle(box)
            box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx
            box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy
            box[:, 0:2][box[:, 0:2]<0] = 0
            box[:, 2][box[:, 2]>w] = w
            box[:, 3][box[:, 3]>h] = h
            box_w = box[:, 2] - box[:, 0]
            box_h = box[:, 3] - box[:, 1]
            box = box[np.logical_and(box_w>1, box_h>1)] # discard invalid box

        return image_data, box
            
    #------------------------------------------#
    #   对图像进行缩放并且进行长和宽的扭曲
    #------------------------------------------#
    new_ar = iw/ih * rand(1-jitter,1+jitter) / rand(1-jitter,1+jitter)
    scale = rand(.25, 2)
    if new_ar < 1:
        nh = int(scale*h)
        nw = int(nh*new_ar)
    else:
        nw = int(scale*w)
        nh = int(nw/new_ar)
    image = image.resize((nw,nh), Image.BICUBIC)

    #------------------------------------------#
    #   将图像多余的部分加上灰条
    #------------------------------------------#
    dx = int(rand(0, w-nw))
    dy = int(rand(0, h-nh))
    new_image = Image.new('RGB', (w,h), (128,128,128))
    new_image.paste(image, (dx, dy))
    image = new_image

    #------------------------------------------#
    #   翻转图像
    #------------------------------------------#
    flip = rand()<.5
    if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT)

    image_data      = np.array(image, np.uint8)
    #---------------------------------#
    #   对图像进行色域变换
    #   计算色域变换的参数
    #---------------------------------#
    r               = np.random.uniform(-1, 1, 3) * [hue, sat, val] + 1
    #---------------------------------#
    #   将图像转到HSV上
    #---------------------------------#
    hue, sat, val   = cv2.split(cv2.cvtColor(image_data, cv2.COLOR_RGB2HSV))
    dtype           = image_data.dtype
    #---------------------------------#
    #   应用变换
    #---------------------------------#
    x       = np.arange(0, 256, dtype=r.dtype)
    lut_hue = ((x * r[0]) % 180).astype(dtype)
    lut_sat = np.clip(x * r[1], 0, 255).astype(dtype)
    lut_val = np.clip(x * r[2], 0, 255).astype(dtype)

    image_data = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))
    image_data = cv2.cvtColor(image_data, cv2.COLOR_HSV2RGB)

    #---------------------------------#
    #   对真实框进行调整
    #---------------------------------#
    if len(box)>0:
        np.random.shuffle(box)
        box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx
        box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy
        if flip: box[:, [0,2]] = w - box[:, [2,0]]
        box[:, 0:2][box[:, 0:2]<0] = 0
        box[:, 2][box[:, 2]>w] = w
        box[:, 3][box[:, 3]>h] = h
        box_w = box[:, 2] - box[:, 0]
        box_h = box[:, 3] - box[:, 1]
        box = box[np.logical_and(box_w>1, box_h>1)] 
    
    return image_data, box

def get_random_data_with_MixUp(image_1, box_1, image_2, box_2):
    new_image = np.array(image_1, np.float32) * 0.5 + np.array(image_2, np.float32) * 0.5
    new_boxes = np.concatenate([box_1, box_2], axis=0)
    return new_image, new_boxes

2、调用代码

该部分为调用代码

import os
from random import sample

import numpy as np
from PIL import Image, ImageDraw

from utils.random_data import get_random_data, get_random_data_with_MixUp
from utils.utils import convert_annotation, get_classes

#-----------------------------------------------------------------------------------#
#   Origin_VOCdevkit_path   原始数据集所在的路径
#-----------------------------------------------------------------------------------#
Origin_VOCdevkit_path   = "VOCdevkit_Origin"
#-----------------------------------------------------------------------------------#
#   input_shape             生成的图片大小。
#-----------------------------------------------------------------------------------#
input_shape             = [640, 640]

if __name__ == "__main__":
    Origin_JPEGImages_path  = os.path.join(Origin_VOCdevkit_path, "VOC2007/JPEGImages")
    Origin_Annotations_path = os.path.join(Origin_VOCdevkit_path, "VOC2007/Annotations")
    
    #---------------------------#
    #   遍历标签并赋值
    #---------------------------#
    xml_names = os.listdir(Origin_Annotations_path)

    #------------------------------#
    #   获取两个图像与标签
    #------------------------------#
    sample_xmls     = sample(xml_names, 2)
    unique_labels   = get_classes(sample_xmls, Origin_Annotations_path)
    jpg_name_1  = os.path.join(Origin_JPEGImages_path, os.path.splitext(sample_xmls[0])[0] + '.jpg')
    jpg_name_2  = os.path.join(Origin_JPEGImages_path, os.path.splitext(sample_xmls[1])[0] + '.jpg')
    xml_name_1  = os.path.join(Origin_Annotations_path, sample_xmls[0])
    xml_name_2  = os.path.join(Origin_Annotations_path, sample_xmls[1])
    
    line_1 = convert_annotation(jpg_name_1, xml_name_1, unique_labels)
    line_2 = convert_annotation(jpg_name_2, xml_name_2, unique_labels)

    #------------------------------#
    #   各自数据增强
    #------------------------------#
    image_1, box_1  = get_random_data(line_1, input_shape) 
    image_2, box_2  = get_random_data(line_2, input_shape) 
    
    #------------------------------#
    #   合并mixup
    #------------------------------#
    image_data, box_data = get_random_data_with_MixUp(image_1, box_1, image_2, box_2)
    
    img = Image.fromarray(image_data.astype(np.uint8))
    for j in range(len(box_data)):
        thickness = 3
        left, top, right, bottom  = box_data[j][0:4]
        draw = ImageDraw.Draw(img)
        for i in range(thickness):
            draw.rectangle([left + i, top + i, right - i, bottom - i],outline=(255, 255, 255))
    img.show()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML5+CSS3(八)-全面详解(学习总结---从入门到深化)

领取详细资料 请关注一下公众号 &#xff01;&#xff01;&#xff01; 目录 领取详细资料 请关注一下公众号 &#xff01;&#xff01;&#xff01; 关系选择器 关系选择器分类 后代选择器 定义 语法 子代选择器 定义 语法 相邻兄弟选择器 定义 语法 通用兄弟选择…

Python爬虫教你爬取视频信息

大家好&#xff0c;我是拉斯&#xff0c;今天分享一个爬取某音视频的一个小案例&#xff0c;大家一起学习 目录前言基本环境配置爬取目标视频获取视频链接1.查看网页源代码2.抓包工具捕捉下载视频(以mp4格式进行保存)获取其他信息并打印(作者名&#xff0c;作品名&#xff0c;…

沁恒CH32V307使用记录:GPIO与EXTI

文章目录目的GPIO&#xff08;通用输入输出接口&#xff09;基础说明初始化输出输入与电平读取锁定机制EXTI&#xff08;外部中断&#xff09;基础说明使用演示总结目的 GPIO是单片机最基础的功能&#xff0c;EXTI最常用的场景就是GPIO用于输入时使用。这篇文章将对CH32V307中…

【i18n】使用 vue-i18n 实现国际化多语言切换

学习关键语句: i18n 进行多语言国际化 使用 vue-i18n 语言切换 写在前面 由于以前没有过国际化的经验 , 所以第一次遇到的时候还是有点懵逼的 , 赶紧在网上转了一大圈 , 分享给大家一点点我的使用经验 我写这篇文章的目的是大家看了之后跟着步骤走就能完成多语言切换的任务 …

闭眼时长标准差脚本

闭眼时长标准差脚本 闭眼时长标准差 平均闭眼时长&#xff1a;识别一分钟内闭眼次数以及每次闭眼的时长&#xff0c;将每次闭眼的时长进行累计相加&#xff0c;最终再取平均值 闭眼标准差公式 闭眼标准差((n1−navg)2(n2−navg)2...)∗1/n闭眼标准差\sqrt{((n_1-n_{avg})^2(…

【广度优先搜索】N叉树的层序遍历 | 腐烂的橘子 | 单词接龙 | 最小基因变化 | 打开转盘锁

&#x1f320;作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《数据结构与算法要啸着学》 &#x1f387;座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;…

jenkins打包构建springboot项目为docker镜像并上传nexus私服

前提&#xff1a;jenkins,docker,nexus都已经搭建完毕 一. 开启docker远程访问 1.修改docker.service文件 Docker 安装成功之后&#xff0c;首先需要修改 Docker 配置来开启允许远程访问 Docker 的功能。     文件位置&#xff1a;/lib/systemd/system/docker.service    …

JVM(Java虚拟机)详解(JVM 内存模型、堆、GC、直接内存、性能调优)

JVM&#xff08;Java虚拟机&#xff09; JVM 内存模型 结构图 jdk1.8 结构图&#xff08;极简&#xff09; jdk1.8 结构图&#xff08;简单&#xff09; JVM&#xff08;Java虚拟机&#xff09;&#xff1a; 是一个抽象的计算模型。如同一台真实的机器&#xff0c;它有自己…

使用比console.log更优质的前端调试方案

程序调试是程序开发必不可少的一环&#xff0c;刚开始接触前端调试时&#xff0c;最常用的就是 console.log 打印变量进行调试&#xff0c;本文会分享一些笔者学习到的前端调试方法&#xff0c;减少对 console.log 调试方式的依赖&#xff0c;选择更优质的前端调试方案。 本文中…

Android开发进阶——RxJava核心架构分析

简介 RxJava是对响应式扩展&#xff08; Reactive Extensions&#xff0c;称之为 ReactiveX &#xff09;规范的Java 实现&#xff0c;该规范还有其他语言实现&#xff1a;RxJS、Rx.Net、RxScala、RxSwift等等&#xff08;也即&#xff0c;ReactiveX 定义了规范&#xff0c;其他…

pip安装时报错 ascii‘ codec can‘t decode byte 0xe2 in position...

在使用pip安装包的时候报错ascii’ codec can’t decode byte 0xe2 in position… 报错信息 UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe2 in position 1429: ordinal not in range(128) 以前好像见过类似的情况&#xff0c;所以搜了一下怎么修改python默认…

聊聊ChatGPT

最近ChatGPT火出圈。 在过去三个月里&#xff0c;眼见着它的热度火箭一般蹿升&#xff0c;据瑞银上周三发布的报告显示&#xff0c;GPT已经超过了Tiktok&#xff0c;成为人类有史以来最快突破1亿月活跃用户的互联网产品。Tiktok当初用了9个月&#xff0c;而GPT只用了2个月。 …

Spring使用了哪些设计模式?

目录Spring中涉及的设计模式总结1.简单工厂(非23种设计模式中的一种)2.工厂方法3.单例模式4.适配器模式5.装饰器模式6.代理模式7.观察者模式8.策略模式9.模版方法模式Spring中涉及的设计模式总结 1.简单工厂(非23种设计模式中的一种) 实现方式&#xff1a; BeanFactory。Spri…

go-grpc的使用和学习

文章目录基础知识&#xff1a;操作流程安装proto文件配置grpc&#xff1a; 正常客户端发送数据(以字节流的方式)&#xff0c;服务器接受并解析&#xff0c;根据约定知道要执行什么&#xff0c;然后把结果返回给客户 rpc将上述过程封装&#xff0c;使其操作更加优化&#xff0c;…

Vue 3 中的极致防抖/节流(含常见方式防抖/节流)

各位朋友你们好呀。今天是立春&#xff0c;明天就是正月十五元宵节了&#xff0c;这种立春 元宵相隔的时候&#xff0c;可是很难遇到的&#xff0c;百年中就只有几次。在这提前祝大家元宵快乐。 今天给大家带来的是Vue 3 中的极致防抖/节流&#xff08;含常见方式防抖/节流&a…

ChatGPT给程序员人手一个,这很朋克

目录ChatGPT、程序员、朋克为什么程序员需要ChatGPT&#xff0c;为什么这很朋克总结ChatGPT、程序员、朋克 本文由ChatGPT编写。 ChatGPT是由OpenAI开发的大型语言模型。它的核心功能是生成人类语言文本&#xff0c;因此有多种应用场景&#xff0c;如文本生成、对话生成、文本…

「VUE架构」Vue2与Vue3的区别

文章目录前言一、性能比Vue2快1.2~2倍1.1 diff算法优化1.2 事件侦听缓存1.3 减少创建组件实例的开销二、 按需编译&#xff0c;体积比Vue2更小三、 Compostion API四、 支持TS五、 自定义渲染API六、更先进的组件七、 更快的开发体验前言 VUE是一套用于构建用户界面的渐进式框…

Nginx常用功能举例解析

Nginx提供的基本功能服务从大体上归纳为"基本HTTP服务"、“高级HTTP服务”和"邮件服务"等三大类。基本HTTP服务Nginx可以提供基本HTTP服务&#xff0c;可以作为HTTP代理服务器和反向代理服务器&#xff0c;支持通过缓存加速访问&#xff0c;可以完成简单的…

【FPGA】Verilog:组合逻辑电路应用 | 数码管 | 8421BCD编码 | 转换七段数码管段码

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;数码管的使用 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器&#xff1a;2M…

Vue-VueRouter

前言 Vue Router 是 Vue.js (opens new window)官方的路由管理器。它和 Vue.js 的核心深度集成&#xff0c;让构建单页面应用变得易如反掌。包含的功能有&#xff1a; 嵌套的路由/视图表模块化的、基于组件的路由配置路由参数、查询、通配符基于 Vue.js 过渡系统的视图过渡效果…