# -*- coding=utf-8 -*-
##############################################################
# description:
# data augmentation for obeject detection
# 参考:https://github.com/maozezhong/CV_ToolBox/blob/master/DataAugForObjectDetection
##############################################################
# 包括:
# 1. 裁剪(需改变bbox)
# 2. 平移(需改变bbox)
# 3. 改变亮度
# 4. 加噪声
# 5. 旋转角度(需要改变bbox)
# 6. 镜像(需要改变bbox)
# 7. cutout
# 注意:
# random.seed(),相同的seed,产生的随机数是一样的!!
import time
import random
import copy
import cv2
import os
import math
import numpy as np
from skimage.util import random_noise
from lxml import etree, objectify
import xml.etree.ElementTree as ET
import argparse
# 显示图片
def show_pic(img, bboxes=None):
'''
输入:
img:图像array
bboxes:图像的所有boudning box list, 格式为[[x_min, y_min, x_max, y_max]....]
names:每个box对应的名称
'''
for i in range(len(bboxes)):
bbox = bboxes[i]
x_min = bbox[0]
y_min = bbox[1]
x_max = bbox[2]
y_max = bbox[3]
cv2.rectangle(img, (int(x_min), int(y_min)), (int(x_max), int(y_max)), (0, 255, 0), 3)
cv2.namedWindow('pic', 0) # 1表示原图
cv2.moveWindow('pic', 0, 0)
cv2.resizeWindow('pic', 1200, 800) # 可视化的图片大小
cv2.imshow('pic', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图像均为cv2读取
class DataAugmentForObjectDetection():
def __init__(self, rotation_rate=0.5, max_rotation_angle=5,
crop_rate=0.5, shift_rate=0.5, change_light_rate=0.5,
add_noise_rate=0.5, flip_rate=0.5,
cutout_rate=0.5, cut_out_length=50, cut_out_holes=1, cut_out_threshold=0.5,
is_addNoise=True, is_changeLight=True, is_cutout=True, is_rotate_img_bbox=True,
is_crop_img_bboxes=True, is_shift_pic_bboxes=True, is_filp_pic_bboxes=True):
# 配置各个操作的属性
self.rotation_rate = rotation_rate
self.max_rotation_angle = max_rotation_angle
self.crop_rate = crop_rate
self.shift_rate = shift_rate
self.change_light_rate = change_light_rate
self.add_noise_rate = add_noise_rate
self.flip_rate = flip_rate
self.cutout_rate = cutout_rate
self.cut_out_length = cut_out_length
self.cut_out_holes = cut_out_holes
self.cut_out_threshold = cut_out_threshold
# 是否使用某种增强方式
self.is_addNoise = True
self.is_changeLight = True
self.is_cutout = True
self.is_rotate_img_bbox = True
self.is_crop_img_bboxes = True
self.is_shift_pic_bboxes = True
self.is_filp_pic_bboxes = True
# 加噪声
def _addNoise(self, img):
'''
输入:
img:图像array
输出:
加噪声后的图像array,由于输出的像素是在[0,1]之间,所以得乘以255
'''
# return cv2.GaussianBlur(img, (11, 11), 0)
return random_noise(img, mode='gaussian', seed=int(time.time()), clip=True) * 255
# 调整亮度
def _changeLight(self, img):
alpha = random.uniform(0.35, 1)
blank = np.zeros(img.shape, img.dtype)
return cv2.addWeighted(img, alpha, blank, 1 - alpha, 0)
# cutout
def _cutout(self, img, bboxes, length=100, n_holes=1, threshold=0.5):
'''
原版本:https://github.com/uoguelph-mlrg/Cutout/blob/master/util/cutout.py
Randomly mask out one or more patches from an image.
Args:
img : a 3D numpy array,(h,w,c)
bboxes : 框的坐标
n_holes (int): Number of patches to cut out of each image.
length (int): The length (in pixels) of each square patch.
'''
def cal_iou(boxA, boxB):
'''
boxA, boxB为两个框,返回iou
boxB为bouding box
'''
# determine the (x, y)-coordinates of the intersection rectangle
xA = max(boxA[0], boxB[0])
yA = max(boxA[1], boxB[1])
xB = min(boxA[2], boxB[2])
yB = min(boxA[3], boxB[3])
if xB <= xA or yB <= yA:
return 0.0
# compute the area of intersection rectangle
interArea = (xB - xA + 1) * (yB - yA + 1)
# compute the area of both the prediction and ground-truth
# rectangles
boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)
iou = interArea / float(boxBArea)
return iou
# 得到h和w
if img.ndim == 3:
h, w, c = img.shape
else:
_, h, w, c = img.shape
mask = np.ones((h, w, c), np.float32)
for n in range(n_holes):
chongdie = True # 看切割的区域是否与box重叠太多
while chongdie:
y = np.random.randint(h)
x = np.random.randint(w)
y1 = np.clip(y - length // 2, 0,
h) # numpy.clip(a, a_min, a_max, out=None), clip这个函数将将数组中的元素限制在a_min, a_max之间,大于a_max的就使得它等于 a_max,小于a_min,的就使得它等于a_min
y2 = np.clip(y + length // 2, 0, h)
x1 = np.clip(x - length // 2, 0, w)
x2 = np.clip(x + length // 2, 0, w)
chongdie = False
for box in bboxes:
if cal_iou([x1, y1, x2, y2], box) > threshold:
chongdie = True
break
mask[y1: y2, x1: x2, :] = 0.
img = img * mask
return img
# 旋转
def _rotate_img_bbox(self, img, bboxes, angle=5, scale=1.):
'''
参考:https://blog.csdn.net/u014540717/article/details/53301195crop_rate
输入:
img:图像array,(h,w,c)
bboxes:该图像包含的所有boundingboxs,一个list,每个元素为[x_min, y_min, x_max, y_max],要确保是数值
angle:旋转角度
scale:默认1
输出:
rot_img:旋转后的图像array
rot_bboxes:旋转后的boundingbox坐标list
'''
# ---------------------- 旋转图像 ----------------------
w = img.shape[1]
h = img.shape[0]
# 角度变弧度
rangle = np.deg2rad(angle) # angle in radians
# now calculate new image width and height
nw = (abs(np.sin(rangle) * h) + abs(np.cos(rangle) * w)) * scale
nh = (abs(np.cos(rangle) * h) + abs(np.sin(rangle) * w)) * scale
# ask OpenCV for the rotation matrix
rot_mat = cv2.getRotationMatrix2D((nw * 0.5, nh * 0.5), angle, scale)
# calculate the move from the old center to the new center combined
# with the rotation
rot_move = np.dot(rot_mat, np.array([(nw - w) * 0.5, (nh - h) * 0.5, 0]))
# the move only affects the translation, so update the translation
rot_mat[0, 2] += rot_move[0]
rot_mat[1, 2] += rot_move[1]
# 仿射变换
rot_img = cv2.warpAffine(img, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)
# ---------------------- 矫正bbox坐标 ----------------------
# rot_mat是最终的旋转矩阵
# 获取原始bbox的四个中点,然后将这四个点转换到旋转后的坐标系下
rot_bboxes = list()
for bbox in bboxes:
xmin = bbox[0]
ymin = bbox[1]
xmax = bbox[2]
ymax = bbox[3]
point1 = np.dot(rot_mat, np.array([(xmin + xmax) / 2, ymin, 1]))
point2 = np.dot(rot_mat, np.array([xmax, (ymin + ymax) / 2, 1]))
point3 = np.dot(rot_mat, np
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
YOLOv8目标检测离线数据增强的方式:首先使用labelme对图像进行标注,将图像和标注文件存放到images和annotations文件夹中,然后使用离线数据增强代码对进行增强。 使用方法: 1.在代码中设置增强次数和文件路径,选择想要数据增强的方式。 2.数据增强完成后需要检查标签的正确性,检查标签是否越界的代码如下。 3.标签可视化代码。
资源推荐
资源详情
资源评论
收起资源包目录
DataAugForObjectDetection.zip (71个子文件)
DataAugForObjectDetection
rename_file.py 559B
data
images2
000003_1.jpg 64KB
000002_2.jpg 77KB
000001_1.jpg 137KB
000001_3.jpg 37KB
000005_4.jpg 77KB
000002_4.jpg 77KB
000005_1.jpg 68KB
000001_4.jpg 41KB
000004_1.jpg 73KB
000002_3.jpg 151KB
000003_4.jpg 153KB
000004_3.jpg 116KB
000003_2.jpg 86KB
000002_1.jpg 87KB
000003_3.jpg 90KB
000001_2.jpg 83KB
000005_5.jpg 55KB
000005_2.jpg 61KB
000002_5.jpg 57KB
000004_5.jpg 98KB
000001_5.jpg 65KB
000004_2.jpg 101KB
000004_4.jpg 167KB
000003_5.jpg 77KB
000005_3.jpg 99KB
images
000002.jpg 111KB
000003.jpg 120KB
000001.jpg 77KB
000004.jpg 100KB
000005.jpg 83KB
annotations
000002.xml 663B
000005.xml 2KB
000004.xml 2KB
000003.xml 874B
000001.xml 879B
annotations2
000005_2.xml 2KB
000001_4.xml 807B
000005_1.xml 2KB
000003_1.xml 810B
000002_4.xml 559B
000005_5.xml 2KB
000001_1.xml 805B
000004_2.xml 2KB
000002_5.xml 559B
000001_5.xml 806B
000002_3.xml 559B
000003_3.xml 809B
000003_2.xml 810B
000004_1.xml 2KB
000004_5.xml 2KB
000001_2.xml 806B
000001_3.xml 807B
000004_4.xml 2KB
000003_5.xml 810B
000003_4.xml 810B
000002_1.xml 559B
000005_4.xml 2KB
000004_3.xml 2KB
000005_3.xml 2KB
000002_2.xml 558B
.idea
workspace.xml 6KB
misc.xml 289B
inspectionProfiles
Project_Default.xml 3KB
profiles_settings.xml 174B
modules.xml 309B
DataAugForObjectDetection.iml 494B
.gitignore 50B
DataAugmentforLabelImg.py 22KB
check.py 1KB
keshihua.py 1KB
共 71 条
- 1
资源评论
AICurator
- 粉丝: 6056
- 资源: 101
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 数据库管理工具:dbeaver-ce-23.1.3-amd64.deb
- 数据库管理工具:dbeaver-ce-23.1.2-amd64.deb
- 数据库管理工具:dbeaver-ce-23.1.1-amd64.deb
- 基于SRM频谱模型的粗糙表面仿真
- 数据库管理工具:dbeaver-ce-23.1.0-amd64.deb
- 数据库管理工具:dbeaver-ce-23.0.4-amd64.deb
- nginx-deploy.yaml
- 编程项目实战:基于ASP.NET架构的学生信息管理系统(含源代码+毕设文档)
- 毕设项目:学生信息管理系统(asp.net+源代码+文档)
- 腾讯研究院2024向AI而行共筑新质生产力-行业大模型调研报告
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功