数据增强方式:调整亮度,对比度,色调,随机缩放,剪切,翻转,旋转等;

Mosaic data augmentation:

  1. Mixup:两张图象按照不同的比例混合,分类结果按照混合比例分配;
  2. Cutout:随机将图片中的区域大小(个人观点裁剪区域图像大小为0.25左右较为合适,比例再大准确率下降明显)裁剪用0填充,结果分类不发生变化;
  3. Cutmix:随机裁剪图像的区域大小,不填充0而是随机选择其他样本的裁剪区域大小填充,结果根据裁剪填充的比例分类【Cutmix = Mixup + Cutout】。
    对比:
    Mixup和Cutmix:前者是将两张图根据设定比例插值融合,如图所示,若隐若现。
    Cutout和Cutmix:前者对随机区域大小使用0填充,后者两张图像的填充。而yolo中类似cutmix使用4张图。
import torch
import torch.nn as nn
import numpy as np# cutmix和mixup的实现代码
def rand_bbox(size, lam):"""随机生成裁剪框大小区域输入参数:图像大小,和随机生成的参数lambda"""W = size[2]H = size[3]# 计算裁剪框区域大小的w和h;cut_rat = np.sqrt(1. - lam)cut_w = np.int(W * cut_rat)cut_h = np.int(H * cut_rat)# uniform# randint函数计算中心点,此处计算中心点cx = np.random.randint(W)cy = np.random.randint(H)# 裁剪区域大小不能超过W和Hbbx1 = np.clip(cx - cut_w // 2, 0, W)bby1 = np.clip(cy - cut_h // 2, 0, H)bbx2 = np.clip(cx + cut_w // 2, 0, W)bby2 = np.clip(cy + cut_h // 2, 0, H)# 返回四个点return bbx1, bby1, bbx2, bby2
def cutmix(data, targets1, targets2, targets3, alpha):indices = torch.randperm(data.size(0))shuffled_data = data[indices]shuffled_targets1 = targets1[indices]shuffled_targets2 = targets2[indices]shuffled_targets3 = targets3[indices]lam = np.random.beta(alpha, alpha) # 随机生成lambda,符合beta分布bbx1, bby1, bbx2, bby2 = rand_bbox(data.size(), lam) # 获得裁剪框data[:, :, bbx1:bbx2, bby1:bby2] = data[indices, :, bbx1:bbx2, bby1:bby2]# adjust lambda to exactly match pixel ratiolam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (data.size()[-1] * data.size()[-2]))targets = [targets1, shuffled_targets1, targets2, shuffled_targets2, targets3, shuffled_targets3, lam]return data, targetsdef mixup(data, targets1, targets2, targets3, alpha):indices = torch.randperm(data.size(0))shuffled_data = data[indices]shuffled_targets1 = targets1[indices]shuffled_targets2 = targets2[indices]shuffled_targets3 = targets3[indices]lam = np.random.beta(alpha, alpha)data = data * lam + shuffled_data * (1 - lam)targets = [targets1, shuffled_targets1, targets2, shuffled_targets2, targets3, shuffled_targets3, lam]return data, targetsdef cutmix_criterion(preds1,preds2,preds3, targets):targets1, targets2,targets3, targets4,targets5, targets6, lam = targets[0], targets[1], targets[2], targets[3], targets[4], targets[5], targets[6]criterion = nn.CrossEntropyLoss(reduction='mean') # 交叉熵损失计算return lam * criterion(preds1, targets1) + (1 - lam) * criterion(preds1, targets2) + lam * criterion(preds2, targets3) + (1 - lam) * criterion(preds2, targets4) + lam * criterion(preds3, targets5) + (1 - lam) * criterion(preds3, targets6)def mixup_criterion(preds1,preds2,preds3, targets):targets1, targets2,targets3, targets4,targets5, targets6, lam = targets[0], targets[1], targets[2], targets[3], targets[4], targets[5], targets[6]criterion = nn.CrossEntropyLoss(reduction='mean')return lam * criterion(preds1, targets1) + (1 - lam) * criterion(preds1, targets2) + lam * criterion(preds2, targets3) + (1 - lam) * criterion(preds2, targets4) + lam * criterion(preds3, targets5) + (1 - lam) * criterion(preds3, targets6)# ==========================================================================================
for i, (image_id, images, label1, label2, label3) in enumerate(data_loader_train):images = images.to(device)label1 = label1.to(device)label2 = label2.to(device)label3 = label3.to(device)# print (image_id, label1, label2, label3)if np.random.rand()<0.5:images, targets = mixup(images, label1, label2, label3, 0.4)output1, output2, output3 = model(images)loss = mixup_criterion(output1,output2,output3, targets) else:images, targets = cutmix(images, label1, label2, label3, 0.4)output1, output2, output3 = model(images)loss = cutmix_criterion(output1,output2,output3, targets)

=====================================================================

import glob
import numpy as np
import matplotlib.pyplot as plt# import torch.nnplt.rcParams['figure.figsize'] = [10, 10]  # 裁剪框大小
import cv2# 数据导入路劲
data_folder = f"./file/"
# 文件夹读取
filenames = glob.glob(f"{data_folder}*.png")
image_paths = filenames[:4]  # 图片数量,
# 显示第一张图片
res = cv2.cvtColor(cv2.imread(image_paths[0]), cv2.COLOR_BGR2RGB)
plt.imshow(res)
plt.show()image_batch = []
image_batch_labels = []
n_images = 4 # 设置文件里包含图片总数
for i in range(4):image = cv2.cvtColor(cv2.imread(image_paths[i]), cv2.COLOR_BGR2RGB)image_batch.append(image)
image_batch_labels = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])# for i in range(2):
#     for j in range(2):
#         plt.subplot(2,2,2*i+j+1)
#         plt.imshow(image_batch[2*i+j])
# plt.show()
# 随机大小框和随机生成的lambda
def rand_bbox(size, lamb):W = size[0]H = size[1]cut_rat = np.sqrt(1. - lamb)cut_w = np.int(W * cut_rat)cut_h = np.int(H * cut_rat)# uniformcx = np.random.randint(W)cy = np.random.randint(H)bbx1 = np.clip(cx - cut_w // 2, 0, W)bby1 = np.clip(cy - cut_h // 2, 0, H)bbx2 = np.clip(cx + cut_w // 2, 0, W)bby2 = np.clip(cy + cut_h // 2, 0, H)return bbx1, bby1, bbx2, bby2# ============================== 显示rand_bbox效果 ==================================
image = cv2.cvtColor(cv2.imread(image_paths[0]), cv2.COLOR_BGR2RGB)
# 裁剪任意lamb大小
lamb = 0.3
size = image.shape
print('size', image.shape)
bbox = rand_bbox(size, lamb)# 在图像上画框框
im = image.copy()
x1 = bbox[0]
y1 = bbox[1]
x2 = bbox[2]
y2 = bbox[3]
cv2.rectangle(im, (x1, y1), (x2, y2), (255, 0, 0), 3) # cv画矩形
plt.imshow(im)
plt.title('Original image with random bounding box')
plt.show()# Show cropped image
plt.imshow(image[y1:y2, x1:x2]);
plt.title('Cropped image')
plt.show()
# ==================================================================================
def generate_cutmix_image(image_batch, image_batch_labels, beta):# 生成混合samplelam = np.random.beta(beta, beta)rand_index = np.random.permutation(len(image_batch))target_a = image_batch_labelstarget_b = np.array(image_batch_labels)[rand_index]print('img.shape', image_batch[0].shape)bbx1, bby1, bbx2, bby2 = rand_bbox(image_batch[0].shape, lam)print('bbx1', bbx1)print('bby1', bby1)print('bbx2', bbx2)print('bby1', bby1)image_batch_updated = image_batch.copy()image_batch_updated = np.array(image_batch_updated)image_batch = np.array(image_batch)image_batch_updated[:, bbx1:bby1, bbx2:bby2, :] = image_batch[rand_index, bbx1:bby1, bbx2:bby2, :]# 调整计算lambda精确像素比例lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (image_batch.shape[1] * image_batch.shape[2]))label = target_a * lam + target_b * (1. - lam)return image_batch_updated, label# image_batch=np.array(image_batch)
# image_batch_updated = image_batch.copy()
# c=[1,0,2,3]
# mm=np.array(image_batch_updated)
# mm[:, 10:200, 10:200, :] = image_batch[c, 10:200, 10:200, :]
# Generate CutMix image
# Let's use the first image of the batch as the input image to be augmented
input_image = image_batch[0]
image_batch_updated, image_batch_labels_updated = generate_cutmix_image(image_batch, image_batch_labels, 1.0)# Show original images
print("Original Images")
for i in range(2):for j in range(2):plt.subplot(2, 2, 2 * i + j + 1)plt.imshow(image_batch[2 * i + j])
plt.show()# Show CutMix images
print("CutMix Images")
for i in range(2):for j in range(2):plt.subplot(2, 2, 2 * i + j + 1)plt.imshow(image_batch_updated[2 * i + j])
plt.show()# Print labels
print('Original labels:')
print(image_batch_labels)
print('Updated labels')
print(image_batch_labels_updated)

=====================================================================
Mosaic登场:Yolov4的mosaic数据增强在CutMix数据增强基础上,利用了四张图片进行拼接得到,其优点是丰富检测物体的背景,且减少计算每个BN中的数据4倍。
读取四张图片->->->->对四张图片进行翻转、缩放、色域变化等,并且按照四个方向位置摆好->->->->图片的组合和框的组合
代码实现

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) + adef 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:continueif y2 >= cuty and y1 <= cuty:y2 = cutyif y2-y1 < 5:continueif x2 >= cutx and x1 <= cutx:x2 = cutxif x2-x1 < 5:continueif i == 1:if y2 < cuty or x1 > cutx:continueif y2 >= cuty and y1 <= cuty:y1 = cutyif y2-y1 < 5:continueif x2 >= cutx and x1 <= cutx:x2 = cutxif x2-x1 < 5:continueif i == 2:if y2 < cuty or x2 < cutx:continueif y2 >= cuty and y1 <= cuty:y1 = cutyif y2-y1 < 5:continueif x2 >= cutx and x1 <= cutx:x1 = cutxif x2-x1 < 5:continueif i == 3:if y1 > cuty or x2 < cutx:continueif y2 >= cuty and y1 <= cuty:y2 = cutyif y2-y1 < 5:continueif x2 >= cutx and x1 <= cutx:x1 = cutxif x2-x1 < 5:continuetmp_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_bboxdef 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_shapemin_offset_x = 0.4min_offset_y = 0.4scale_low = 1-min(min_offset_x,min_offset_y)scale_high = scale_low+0.2image_datas = [] box_datas = []index = 0place_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()<.5if flip and len(box)>0:image = image.transpose(Image.FLIP_LEFT_RIGHT)box[:, [0,2]] = iw - box[:, [2,0]]# 对输入进来的图片进行缩放new_ar = w/hscale = 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] += huex[..., 0][x[..., 0]>1] -= 1x[..., 0][x[..., 0]<0] += 1x[..., 1] *= satx[..., 2] *= valx[x>1] = 1x[x<0] = 0image = 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 + 1box_data = []# 对box进行重新处理if len(box)>0:np.random.shuffle(box)box[:, [0,2]] = box[:, [0,2]]*nw/iw + dxbox[:, [1,3]] = box[:, [1,3]]*nh/ih + dybox[:, 0:2][box[:, 0:2]<0] = 0box[:, 2][box[:, 2]>w] = wbox[:, 3][box[:, 3]>h] = hbox_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)] = boximage_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 = 3left, 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_boxesif __name__ == "__main__":with open("2007_train.txt") as f:lines = f.readlines()a = np.random.randint(0,len(lines))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 = 3left, 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")

【数据增强 Random Erase】
【数据增强 Hide and Seek】
【数据增强 FMix 的代码】

Yolo-V4数据增强相关推荐

  1. yolo imgaug数据增强 标签同时也增强

    原文:https://blog.csdn.net/m0_37940759/article/details/115212083 完整代码: import xml.etree.ElementTree as ...

  2. YOLO自带的图像数据增强方法

    yolo数据增强code: V3: https://github.com/ultralytics/yolov3/blob/master/utils/datasets.py V4: https://gi ...

  3. 图像数据增强2_albumentation 标注框同时修改(VOC、YOLO)

    主要参考: 图像样本增广,yoloV5扩展 Albumentation库 bbox使用案例代码 [YOLOV5-5.x 源码解读]general.py 这里写目录标题 albumentation 标注 ...

  4. yolo数据增强以及批量修改图片和xml名

    记录下打完标签对数据集进行扩增,数据增强后的图片及标签名字进行修改,重点在代码只需更改文件名就可使用 无论数据增强还是修改名称,标签框位置都会跟着改变!!! 前人之鉴,最好还是数据增强后再去打标签,千 ...

  5. YOLO v1到YOLO v4(上)

    YOLO v1到YOLO v4(上) 一. YOLO v1 这是继RCNN,fast-RCNN和faster-RCNN之后,rbg(RossGirshick)针对DL目标检测速度问题提出的另外一种框架 ...

  6. 全面解析YOLO V4网络结构

    作者|周威,https://zhuanlan.zhihu.com/p/150127712 本文已获作者授权,不得二次转载. 1.前言 最近用YOLO V4做车辆检测,配合某一目标追踪算法实现车辆追踪+ ...

  7. YOLO v4它来了:接棒者出现,速度效果双提升

    来源:机器之心 本文约2188字,建议阅读7分钟. 本文介绍YOLO 的官方 Github 账号更新了 YOLO v4 的 arXiv 链接与开源代码链接,迅速引起了 CV 社区的关注. 两个月前,Y ...

  8. 从原理到实操,看当前最佳的YOLO V4是如何炼成的?

    YOLO系列的网络都有一个共同的特点,即追求网络精度也追求网络速度,YOLO V4在此基础上又多了一个追求,那就是降低硬件要求. YOLO V4 的开发历程很有意思,其中评估.修改和整合了很多有趣的新 ...

  9. 全面解析YOLO V4网络结构(附代码讲解)

    点击上方"深度学习技术前沿",选择"星标"公众号 精选作品,第一时间送达 作者:周威 链接:https://zhuanlan.zhihu.com/p/15012 ...

  10. 深度学习目标检测之 YOLO v4

    论文原文:https://arxiv.org/abs/2004.10934 代码 原版c++: https://github.com/AlexeyAB/darknet keras:https://gi ...

最新文章

  1. 访问控制允许原始多个域?
  2. aMCMC for Horseshoe: algorithms
  3. CKMLCP前期未结算_报错
  4. chrome开发者工具各种骚技巧
  5. datatable转list方法(有借鉴到他人)
  6. ManjarorLinux操作笔记
  7. java applog_个人app如何收集用户日志
  8. 图片如何转PDF格式?这些方法值得收藏
  9. visio2010最新密钥
  10. vscode安装程序员鼓励师插件
  11. android中TextView属性之autoText解析
  12. RT1021使用RTS引脚控制RS485芯片收发使能
  13. 究竟云计算就业前景好不好 零基础如何学云计算
  14. 【随笔】移动端input type|语义与IOS按键
  15. Rhino6.5软件安装教程|兼容WIN10
  16. win10 安装“msi”文件提示 “Windows Installer无法打开此安装程序包。请确认该程序包存在,并且你有权访问它,或者与应用程序供应商联” error 2502 2503
  17. 王建宙五进36dj中挪动包围国际化
  18. JavaScript今日所学 数组
  19. MYSQL(连接查询)
  20. java 数据类型cher,java期末考试题96534-(20008)

热门文章

  1. 山东大学为什么火了_关于最近很“火”的话题,山东大学学伴制度的看法
  2. Sedona NetFusion 在OIF/ONF T-API 互通测试中扮演关键角色
  3. 【USACO题库】3.2.4 Feed Ratios饲料调配
  4. 智能体重秤方案/案列/APP/小程序
  5. laravel Scout包在elasticsearch中的应用
  6. 2020.8.13 京东Android开发二面
  7. iOS字体大小适配的几种方法
  8. 黑马程序员---java基础-Java之IO
  9. 阿里云CAC_DevOps课程详细文字文档
  10. Spring项目-在线五子棋