使用 Python 和 OpenCV 进行数据增广

重磅干货,第一时间送达

数据扩充是一种增加数据集多样性的技术,无需收集更多真实数据,但仍有助于提高模型精度并防止模型过度拟合。在这篇文章中,我们将学习使用 Python 和 OpenCV 为对象检测任务实现最流行和最有效的数据扩充过程。

即将引入的一组数据扩充方法包括:

  1. 随机裁剪

  2. 断流器

  3. 颜色抖动

  4. 添加噪音

  5. 过滤

首先,让我们导入几个库并准备一些必要的子程序。

import osimport cv2import numpy as npimport random
def file_lines_to_list(path):''' ### Convert Lines in TXT File to List ### path: path to file '''with open(path) as f: content = f.readlines() content = [(x.strip()).split() for x in content]return content
def get_file_name(path):''' ### Get Filename of Filepath ### path: path to file ''' basename = os.path.basename(path) onlyname = os.path.splitext(basename)[0]return onlyname
def write_anno_to_txt(boxes, filepath):''' ### Write Annotation to TXT File ### boxes: format [[obj x1 y1 x2 y2],...] filepath: path/to/file.txt ''' txt_file = open(filepath, "w")for box in boxes: print(box[0], int(box[1]), int(box[2]), int(box[3]), int(box[4]), file=txt_file) txt_file.close()

下面的图片在这篇文章中用作示例图片。

随机裁剪

随机裁剪随机选择一个区域并裁剪出来做一个新的数据样本,裁剪后的区域应该与原始图像具有相同的宽高比以保持物体的形状。

从上图中,左图表示带有真实边界框(红色)的原始图像,右图是通过裁剪橙色框内的区域创建的新样本。在新样本的注释中,去除左图中与橙色框不重叠的所有对象,并细化位于橙色框边界上的对象的坐标以适合新图像样本,原始图像随机裁剪的输出为新裁剪图像及其注释。

def randomcrop(img, gt_boxes, scale=0.5):''' ### Random Crop ### img: image gt_boxes: format [[obj x1 y1 x2 y2],...] scale: percentage of cropped area '''
# Crop image height, width = int(img.shape[0]*scale), int(img.shape[1]*scale) x = random.randint(0, img.shape[1] - int(width)) y = random.randint(0, img.shape[0] - int(height)) cropped = img[y:y+height, x:x+width] resized = cv2.resize(cropped, (img.shape[1], img.shape[0]))
# Modify annotation new_boxes=[]for box in gt_boxes: obj_name = box[0] x1 = int(box[1]) y1 = int(box[2]) x2 = int(box[3]) y2 = int(box[4]) x1, x2 = x1-x, x2-x y1, y2 = y1-y, y2-y x1, y1, x2, y2 = x1/scale, y1/scale, x2/scale, y2/scaleif (x1<img.shape[1] and y1<img.shape[0]) and (x2>0 and y2>0):if x1<0: x1=0if y1<0: y1=0if x2>img.shape[1]: x2=img.shape[1]if y2>img.shape[0]: y2=img.shape[0] new_boxes.append([obj_name, x1, y1, x2, y2])return resized, new_boxes
断流器

断流器由Terrance DeVries和Graham W. Taylor在 2017 年在他们的论文中提出,是一种简单的正则化技术,可在训练过程中随机屏蔽输入的方形区域,可用于提高卷积神经网络的鲁棒性和整体性能。这种方法不仅非常容易实现,而且还表明它可以与现有形式的数据扩充和其他正则化工具结合使用,以进一步提高模型性能。

如本文所述,断流器被用于提高图像识别(分类)的准确性,因此,如果我们将相同的方案部署到对象检测数据集中,可能会导致丢失对象的问题,尤其是小对象。下图中,剪切区域(黑色区域)内的大量的小物体被去除了,这不符合数据扩充的目的。

为了使这种方式适用于对象检测,我们可以做一个简单的修改,而不是只使用一个掩码并将其放在图像中的随机位置,当我们随机选择一半数量的对象并将断流器应用于这些对象区域时,效果会更好。增强图像如下图中的右图所示。

剪切输出是一张新生成的图像,我们不去除对象或改变图像大小,那么生成的图像的注释与原始图像相同。

def cutout(img, gt_boxes, amount=0.5):''' ### Cutout ###img: imagegt_boxes: format [[obj x1 y1 x2 y2],...]amount: num of masks / num of objects '''out = img.copy()ran_select = random.sample(gt_boxes, round(amount*len(gt_boxes)))
for box in ran_select:x1 = int(box[1])y1 = int(box[2])x2 = int(box[3])y2 = int(box[4])mask_w = int((x2 - x1)*0.5)mask_h = int((y2 - y1)*0.5)mask_x1 = random.randint(x1, x2 - mask_w)mask_y1 = random.randint(y1, y2 - mask_h)mask_x2 = mask_x1 + mask_wmask_y2 = mask_y1 + mask_hcv2.rectangle(out, (mask_x1, mask_y1), (mask_x2, mask_y2), (0, 0, 0), thickness=-1)return out
颜色抖动

颜色抖动是另一种简单类型的图像数据增强,我们可以随机改变图像的亮度、对比度和饱和度。

def colorjitter(img, cj_type="b"):''' ### Different Color Jitter ###img: imagecj_type: {b: brightness, s: saturation, c: constast}'''if cj_type == "b": # value = random.randint(-50, 50)value = np.random.choice(np.array([-50, -40, -30, 30, 40, 50]))hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)h, s, v = cv2.split(hsv)if value >= 0:lim = 255 - valuev[v > lim] = 255v[v <= lim] += valueelse:lim = np.absolute(value)v[v < lim] = 0v[v >= lim] -= np.absolute(value)
final_hsv = cv2.merge((h, s, v))img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)return img
elif cj_type == "s": # value = random.randint(-50, 50)value = np.random.choice(np.array([-50, -40, -30, 30, 40, 50]))hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)h, s, v = cv2.split(hsv)if value >= 0:lim = 255 - values[s > lim] = 255s[s <= lim] += valueelse:lim = np.absolute(value)s[s < lim] = 0s[s >= lim] -= np.absolute(value)
final_hsv = cv2.merge((h, s, v))img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)return img
elif cj_type == "c":brightness = 10contrast = random.randint(40, 100)dummy = np.int16(img)dummy = dummy * (contrast/127+1) - contrast + brightnessdummy = np.clip(dummy, 0, 255)img = np.uint8(dummy)return img
添加噪音

在一般意义上,噪声被认为是图像中意想不到的因素,然而,可以利用几种类型的噪声(例如,高斯噪声、脉冲噪声)进行数据增强,在深度学习中添加噪声是一种非常简单和有益的数据增强方法。在下面示例中,为了数据增强,将高斯噪声和脉冲噪声添加到原始图像中。

对于那些无法识别高斯噪声和脉冲噪声之间差异的人,高斯噪声的值范围从 0 到 255 ,具体取决于配置,因此,在 RGB 图像中,高斯噪声像素可以是任何颜色。相比之下,脉冲噪声像素只能有两个值 0 或 255,分别为黑色或白色。

def noisy(img, noise_type="gauss"):''' ### Adding Noise ### img: image cj_type: {gauss: gaussian, sp: salt & pepper}
'''if noise_type == "gauss": image=img.copy() mean=0 st=0.7 gauss = np.random.normal(mean,st,image.shape) gauss = gauss.astype('uint8') image = cv2.add(image,gauss)return image
elif noise_type == "sp": image=img.copy() prob = 0.05if len(image.shape) == 2: black = 0 white = 255else: colorspace = image.shape[2]if colorspace == 3: # RGB black = np.array([0, 0, 0], dtype='uint8') white = np.array([255, 255, 255], dtype='uint8')else: # RGBA black = np.array([0, 0, 0, 255], dtype='uint8') white = np.array([255, 255, 255, 255], dtype='uint8') probs = np.random.random(image.shape[:2]) image[probs < (prob / 2)] = black image[probs > 1 - (prob / 2)] = whitereturn image
过滤

过滤是这篇文章中介绍的最后一个数据扩充过程,与添加噪声类似,过滤也很简单且易于实现。实现中使用的三种类型的过滤包括模糊 (平均)、高斯和中值。

def filters(img, f_type = "blur"):''' ### Filtering ### img: image f_type: {blur: blur, gaussian: gaussian, median: median}
'''if f_type == "blur": image=img.copy() fsize = 9return cv2.blur(image,(fsize,fsize))
elif f_type == "gaussian": image=img.copy() fsize = 9return cv2.GaussianBlur(image, (fsize, fsize), 0)
elif f_type == "median": image=img.copy() fsize = 9return cv2.medianBlur(image, fsize)
总结

Github代码连接:

https://github.com/tranleanh/data-augmentation

(0)

相关推荐

  • 弹幕君,别挡着我看小姐姐!

    某天代码写得老眼昏花,去B站上摸鱼,突然发现奇怪的现象: 哟呵,B站竟然做了视频前景提取,把弹幕藏到画面人物的后面.识别效果还意外地不错呢. 然后又翻了下,发现这是个叫做"智能防挡弹幕&qu ...

  • python+opencv图像处理(四十二)

    Kirsch算子 1.Kirsch算子 Kirsch算子是R.Kirsch提出来一种边缘检测新算法,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方 ...

  • python进阶—OpenCV之图像处理(一)

    文章目录 颜色空间转换 RGB色彩空间 HSV色彩空间 YUV色彩空间 简单的物体跟踪示例 HSV空间目标阈值选取 图像几何变换 图像的缩放 图像的位移 图像的旋转 图像的仿射 图像的投射 图像阈值( ...

  • 一个简单方法识别毛玻璃、高斯模糊

    作者:晟沚 前  言 本文主要推荐一种简单的方法识别带有毛玻璃.高斯模糊等效果的图片. 01 毛玻璃效果 毛玻璃效果的原理,即遍历每一个像素,随机选取这个像素周围的某一个像素,替换当前像素.可以使用o ...

  • 使用Python+OpenCV进行数据增广方法综述(附代码演练)

    原创 磐怼怼 深度学习与计算机视觉 1周前 数据扩充是一种增加数据集多样性的技术,无需收集更多的真实数据,但仍然有助于提高模型的准确性和防止模型过度拟合.在这篇文章中,你将学习使用Python和Ope ...

  • 涨点技巧!小目标检测:数据增广

    近年来,目标检测算法取得了很好的成绩,但是,小目标和大目标的检测性能差异较大.小目标检测是目标检测中必不可少且具有挑战性的问题,在人脸检测.交通标记.缺陷检测等领域都是其重要挑战.缓解小目标检测问题的 ...

  • 赛尔笔记 | 自然语言处理领域的数据增广方法

    作者:哈工大SCIR 李博涵 1.摘要 本文介绍自然语言处理领域的数据增广方法.数据增广(Data Augmentation,也有人将Data Augmentation翻译为"数据增强&qu ...

  • 基于深度学习的数据增广技术一览

    加入极市专业CV交流群,与 10000+来自港科大.北大.清华.中科院.CMU.腾讯.百度 等名校名企视觉开发者互动交流! 同时提供每月大咖直播分享.真实项目需求对接.干货资讯汇总,行业技术交流.关注 ...

  • 谷歌简单粗暴“复制-粘贴”数据增广,刷新COCO目标检测与实例分割新高度

    近日,谷歌.UC伯克利与康奈尔大学的研究人员公布了一篇论文 Simple Copy-Paste is a Strong Data Augmentation Method for Instance Se ...

  • 青出于蓝而胜于蓝,超越MixUp、CutMix的样本混合数据增广新算法FMix

    深度学习实践中,数据的增广有很多种方法,比如在计算机视觉任务中除了常规的对单样本进行缩放.颜色扰动.旋转.镜像等外,也可以通过对两个样本进行混合,生成新的虚拟样本训练集.这类方法被称为样本混合数据增广 ...

  • 增广贤文

    昔时贤文,诲汝谆谆. 集韵增广,多见多闻. 观今宜鉴古,无古不成今. [解释]用以前圣贤们的言论,来谆谆教诲你.广泛搜集押韵的文字汇编成"增广",使你见多识广.应该借鉴古人的经验教 ...

  • 《增广贤文》22句至理名言,句句是经典

    "增广贤文"的内容大致可分为以下几个方面:一是讲人与人的关系,二是讲命运,三是讲人生,四是讲读书.文章中有许多强调命运与报应的内容,认为人的一切都是命运安排的,人应该行善,才会有美 ...

  • 《增广贤文》中最“毒”的6句话,字字珠玑,揭露了现实和人性

    俗语指广泛性流行于民间的简明扼要的语句,体现了劳动者的日常生活实践经验. 明朝的<增广贤文>便是1本民间俗语的集录,这其中的许多 语句都非常有现实意义. 今儿要介绍<增广贤文> ...