python目标检测YoloV4当中的Mosaic数据增强方法

目录
  • 什么是Mosaic数据增强方法
  • 实现思路
  • 全部代码

什么是Mosaic数据增强方法

Yolov4的mosaic数据增强参考了CutMix数据增强方式,理论上具有一定的相似性!

CutMix数据增强方式利用两张图片进行拼接。

但是mosaic利用了四张图片,根据论文所说其拥有一个巨大的优点是丰富检测物体的背景!且在BN计算的时候一下子会计算四张图片的数据!就像下图这样:

实现思路

1、每次读取四张图片。

2、分别对四张图片进行翻转、缩放、色域变化等,并且按照四个方向位置摆好。

3、进行图片的组合和框的组合

全部代码

全部代码构成如下:

from PIL import Image, ImageDraw
import numpy as np
from matplotlib.colors import rgb_to_hsv, hsv_to_rgb
import math
def rand(a=0, b=1):
    return np.random.rand()*(b-a) + a
def merge_bboxes(bboxes, cutx, cuty):
    merge_bbox = []
    for i in range(len(bboxes)):
        for box in bboxes[i]:
            tmp_box = []
            x1,y1,x2,y2 = box[0], box[1], box[2], box[3]
            if i == 0:
                if y1 > cuty or x1 > cutx:
                    continue
                if y2 >= cuty and y1 <= cuty:
                    y2 = cuty
                    if y2-y1 < 5:
                        continue
                if x2 >= cutx and x1 <= cutx:
                    x2 = cutx
                    if x2-x1 < 5:
                        continue
            if i == 1:
                if y2 < cuty or x1 > cutx:
                    continue
                if y2 >= cuty and y1 <= cuty:
                    y1 = cuty
                    if y2-y1 < 5:
                        continue
                if x2 >= cutx and x1 <= cutx:
                    x2 = cutx
                    if x2-x1 < 5:
                        continue
            if i == 2:
                if y2 < cuty or x2 < cutx:
                    continue
                if y2 >= cuty and y1 <= cuty:
                    y1 = cuty
                    if y2-y1 < 5:
                        continue
                if x2 >= cutx and x1 <= cutx:
                    x1 = cutx
                    if x2-x1 < 5:
                        continue
            if i == 3:
                if y1 > cuty or x2 < cutx:
                    continue
                if y2 >= cuty and y1 <= cuty:
                    y2 = cuty
                    if y2-y1 < 5:
                        continue
                if x2 >= cutx and x1 <= cutx:
                    x1 = cutx
                    if x2-x1 < 5:
                        continue
            tmp_box.append(x1)
            tmp_box.append(y1)
            tmp_box.append(x2)
            tmp_box.append(y2)
            tmp_box.append(box[-1])
            merge_bbox.append(tmp_box)
    return merge_bbox
def get_random_data(annotation_line, input_shape, random=True, hue=.1, sat=1.5, val=1.5, proc_img=True):
    '''random preprocessing for real-time data augmentation'''
    h, w = input_shape
    min_offset_x = 0.4
    min_offset_y = 0.4
    scale_low = 1-min(min_offset_x,min_offset_y)
    scale_high = scale_low+0.2
    image_datas = []
    box_datas = []
    index = 0
    place_x = [0,0,int(w*min_offset_x),int(w*min_offset_x)]
    place_y = [0,int(h*min_offset_y),int(w*min_offset_y),0]
    for line in annotation_line:
        # 每一行进行分割
        line_content = line.split()
        # 打开图片
        image = Image.open(line_content[0])
        image = image.convert("RGB")
        # 图片的大小
        iw, ih = image.size
        # 保存框的位置
        box = np.array([np.array(list(map(int,box.split(',')))) for box in line_content[1:]])
        # image.save(str(index)+".jpg")
        # 是否翻转图片
        flip = rand()<.5
        if flip and len(box)>0:
            image = image.transpose(Image.FLIP_LEFT_RIGHT)
            box[:, [0,2]] = iw - box[:, [2,0]]
        # 对输入进来的图片进行缩放
        new_ar = w/h
        scale = rand(scale_low, scale_high)
        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)
        # 进行色域变换
        hue = rand(-hue, hue)
        sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat)
        val = rand(1, val) if rand()<.5 else 1/rand(1, val)
        x = rgb_to_hsv(np.array(image)/255.)
        x[..., 0] += hue
        x[..., 0][x[..., 0]>1] -= 1
        x[..., 0][x[..., 0]<0] += 1
        x[..., 1] *= sat
        x[..., 2] *= val
        x[x>1] = 1
        x[x<0] = 0
        image = hsv_to_rgb(x)
        image = Image.fromarray((image*255).astype(np.uint8))
        # 将图片进行放置,分别对应四张分割图片的位置
        dx = place_x[index]
        dy = place_y[index]
        new_image = Image.new('RGB', (w,h), (128,128,128))
        new_image.paste(image, (dx, dy))
        image_data = np.array(new_image)/255
        # Image.fromarray((image_data*255).astype(np.uint8)).save(str(index)+"distort.jpg")
        index = index + 1
        box_data = []
        # 对box进行重新处理
        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)]
            box_data = np.zeros((len(box),5))
            box_data[:len(box)] = box
        image_datas.append(image_data)
        box_datas.append(box_data)
        img = Image.fromarray((image_data*255).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()
    # 将图片分割,放在一起
    cutx = np.random.randint(int(w*min_offset_x), int(w*(1 - min_offset_x)))
    cuty = np.random.randint(int(h*min_offset_y), int(h*(1 - min_offset_y)))
    new_image = np.zeros([h,w,3])
    new_image[:cuty, :cutx, :] = image_datas[0][:cuty, :cutx, :]
    new_image[cuty:, :cutx, :] = image_datas[1][cuty:, :cutx, :]
    new_image[cuty:, cutx:, :] = image_datas[2][cuty:, cutx:, :]
    new_image[:cuty, cutx:, :] = image_datas[3][:cuty, cutx:, :]
    # 对框进行进一步的处理
    new_boxes = merge_bboxes(box_datas, cutx, cuty)
    return new_image, new_boxes
def normal_(annotation_line, input_shape):
    '''random preprocessing for real-time data augmentation'''
    line = annotation_line.split()
    image = Image.open(line[0])
    box = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]])
    iw, ih = image.size
    image = image.transpose(Image.FLIP_LEFT_RIGHT)
    box[:, [0,2]] = iw - box[:, [2,0]]
    return image, box
if __name__ == "__main__":
    with open("2007_train.txt") as f:
        lines = f.readlines()
    a = np.random.randint(0,len(lines))
    # index = 0
    # line_all = lines[a:a+4]
    # for line in line_all:
    #     image_data, box_data = normal_(line,[416,416])
    #     img = image_data
    #     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()
    #     # img.save(str(index)+"box.jpg")
    #     index = index+1
    line = lines[a:a+4]
    image_data, box_data = get_random_data(line,[416,416])
    img = Image.fromarray((image_data*255).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()
    # img.save("box_all.jpg")

以上就是python目标检测YoloV4当中的Mosaic数据增强方法的详细内容,更多关于YoloV4 Mosaic数据增强的资料请关注我们其它相关文章!

(0)

相关推荐

  • 基于Python的图像数据增强Data Augmentation解析

    1.1 简介 深层神经网络一般都需要大量的训练数据才能获得比较理想的结果.在数据量有限的情况下,可以通过数据增强(Data Augmentation)来增加训练样本的多样性, 提高模型鲁棒性,避免过拟合. 在计算机视觉中,典型的数据增强方法有翻转(Flip),旋转(Rotat ),缩放(Scale),随机裁剪或补零(Random Crop or Pad),色彩抖动(Color jittering),加噪声(Noise) 笔者在跟进视频及图像中的人体姿态检测和关键点追踪(Human Pose Es

  • Python深度学习albumentations数据增强库

    数据增强的必要性 深度学习在最近十年得以风靡得益于计算机算力的提高以及数据资源获取的难度下降.一个好的深度模型往往需要大量具有label的数据,使得模型能够很好的学习这种数据的分布.而给数据打标签往往是一件耗时耗力的工作. 拿cv里的经典任务为例,classification需要人准确识别物品类别或者生物种类,object detection需要人工画出bounding box, 确定其坐标,semantic segmentation甚至需要在像素级别进行标签标注.对于一些专业领域的图像标注,依

  • python目标检测数据增强的代码参数解读及应用

    目录 数据增强做了什么 目标检测中的图像增强 全部代码 数据增强做了什么 数据增强是非常重要的提高目标检测算法鲁棒性的手段,学习一下对身体有好处! 数据增强其实就是让图片变得更加多样.比如说原图是一个电脑 如果不使用数据增强的话这个电脑就只是一个电脑,每次训练的电脑都是这样的样子的,但是我们实际生活中电脑是多样的. 因此我们可以通过改变亮度,图像扭曲等方式使得图像变得更加多种多样,如下图所示,尽管亮度,形态发生了细微改变,但本质上,这些东西都依然是电脑. 改变后的图片放入神经网络进行训练可以提高

  • Keras 数据增强ImageDataGenerator多输入多输出实例

    我就废话不多说了,大家还是直接看代码吧~ import os os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" os.environ["CUDA_VISIBLE_DEVICES"]="" import sys import gc import time import cv2 import random import numpy as np import pandas as pd impo

  • python神经网络学习数据增强及预处理示例详解

    目录 学习前言 处理长宽不同的图片 数据增强 1.在数据集内进行数据增强 2.在读取图片的时候数据增强 3.目标检测中的数据增强 学习前言 进行训练的话,如果直接用原图进行训练,也是可以的(就如我们最喜欢Mnist手写体),但是大部分图片长和宽不一样,直接resize的话容易出问题. 除去resize的问题外,有些时候数据不足该怎么办呢,当然要用到数据增强啦. 这篇文章就是记录我最近收集的一些数据预处理的方式 处理长宽不同的图片 对于很多分类.目标检测算法,输入的图片长宽是一样的,如224,22

  • python目标检测YoloV4当中的Mosaic数据增强方法

    目录 什么是Mosaic数据增强方法 实现思路 全部代码 什么是Mosaic数据增强方法 Yolov4的mosaic数据增强参考了CutMix数据增强方式,理论上具有一定的相似性! CutMix数据增强方式利用两张图片进行拼接. 但是mosaic利用了四张图片,根据论文所说其拥有一个巨大的优点是丰富检测物体的背景!且在BN计算的时候一下子会计算四张图片的数据!就像下图这样: 实现思路 1.每次读取四张图片. 2.分别对四张图片进行翻转.缩放.色域变化等,并且按照四个方向位置摆好. 3.进行图片的

  • python目标检测给图画框,bbox画到图上并保存案例

    我就废话不多说了,还是直接上代码吧! import os import xml.dom.minidom import cv2 as cv ImgPath = 'C:/Users/49691/Desktop/gangjin/gangjin_test/JPEGImages/' AnnoPath = 'C:/Users/49691/Desktop/gangjin/gangjin_test/Annotations/' #xml文件地址 save_path = '' def draw_anchor(Img

  • python目标检测SSD算法训练部分源码详解

    目录 学习前言 讲解构架 模型训练的流程 1.设置参数 2.读取数据集 3.建立ssd网络. 4.预处理数据集 5.框的编码 6.计算loss值 7.训练模型并保存 开始训练 学习前言 ……又看了很久的SSD算法,今天讲解一下训练部分的代码.预测部分的代码可以参照https://blog.csdn.net/weixin_44791964/article/details/102496765 讲解构架 本次教程的讲解主要是对训练部分的代码进行讲解,该部分讲解主要是对训练函数的执行过程与执行思路进行详

  • python目标检测yolo2详解及预测代码复现

    目录 前言 实现思路 1.yolo2的预测思路(网络构建思路) 2.先验框的生成 3.利用先验框对网络的输出进行解码 4.进行得分排序与非极大抑制筛选 实现结果 前言 ……最近在学习yolo1.yolo2和yolo3,写这篇博客主要是为了让自己对yolo2的结构有更加深刻的理解,同时要理解清楚先验框的含义. 尽量配合代码观看会更容易理解. 直接下载 实现思路 1.yolo2的预测思路(网络构建思路) YOLOv2使用了一个新的分类网络DarkNet19作为特征提取部分,DarkNet19包含19

  • python目标检测yolo3详解预测及代码复现

    目录 学习前言 实现思路 1.yolo3的预测思路(网络构建思路) 2.利用先验框对网络的输出进行解码 3.进行得分排序与非极大抑制筛选 实现结果 学习前言 对yolo2解析完了之后当然要讲讲yolo3,yolo3与yolo2的差别主要在网络的特征提取部分,实际的解码部分其实差距不大 代码下载 本次教程主要基于github中的项目点击直接下载,该项目相比于yolo3-Keras的项目更容易看懂一些,不过它的许多代码与yolo3-Keras相同. 我保留了预测部分的代码,在实际可以通过执行dete

  • python目标检测实现黑花屏分类任务示例

    目录 背景 核心技术与架构图 技术实现 1.数据的标注 2.训练过程 3.损失的计算 4.对输出内容的处理 效果展示 总结 背景 视频帧的黑.花屏的检测是视频质量检测中比较重要的一部分,传统做法是由测试人员通过肉眼来判断视频中是否有黑.花屏的现象,这种方式不仅耗费人力且效率较低. 为了进一步节省人力.提高效率,一种自动的检测方法是大家所期待的.目前,通过分类网络模型对视频帧进行分类来自动检测是否有黑.花屏是比较可行且高效的. 然而,在项目过程中,视频帧数据的收集比较困难,数据量较少,部分花屏和正

  • python:目标检测模型预测准确度计算方式(基于IoU)

    训练完目标检测模型之后,需要评价其性能,在不同的阈值下的准确度是多少,有没有漏检,在这里基于IoU(Intersection over Union)来计算. 希望能提供一些思路,如果觉得有用欢迎赞我表扬我~ IoU的值可以理解为系统预测出来的框与原来图片中标记的框的重合程度.系统预测出来的框是利用目标检测模型对测试数据集进行识别得到的. 计算方法即检测结果DetectionResult与GroundTruth的交集比上它们的并集,如下图: 蓝色的框是:GroundTruth 黄色的框是:Dete

  • python目标检测IOU的概念与示例

    目录 学习前言 什么是IOU IOU的特点 全部代码 学习前言 神经网络的应用还有许多,目标检测就是其中之一,目标检测中有一个很重要的概念便是IOU 什么是IOU IOU是一种评价目标检测器的一种指标. 下图是一个示例:图中绿色框为实际框(好像不是很绿……),红色框为预测框,当我们需要判断两个框之间的关系时,需要用什么指标呢? 此时便需要用到IOU. 计算IOU的公式为: 可以看到IOU是一个比值,即交并比. 在分子部分,值为预测框和实际框之间的重叠区域: 在分母部分,值为预测框和实际框所占有的

  • python目标检测SSD算法预测部分源码详解

    目录 学习前言 什么是SSD算法 ssd_vgg_300主体的源码 学习前言 ……学习了很多有关目标检测的概念呀,咕噜咕噜,可是要怎么才能进行预测呢,我看了好久的SSD源码,将其中的预测部分提取了出来,训练部分我还没看懂 什么是SSD算法 SSD是一种非常优秀的one-stage方法,one-stage算法就是目标检测和分类是同时完成的,其主要思路是均匀地在图片的不同位置进行密集抽样,抽样时可以采用不同尺度和长宽比,然后利用CNN提取特征后直接进行分类与回归,整个过程只需要一步,所以其优势是速度

随机推荐