使用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)

相关推荐

  • 好玩的OpenCV:图像操作的基本知识(2)

    1.1随机生成像素 生成与test.jpg相同大小图片,但是像素是随机生成的. import numpy as np import cv2raw_image = cv2.imread('test图片路 ...

  • 基于OpenCV的区域分割、轮廓检测和阈值处理

    重磅干货,第一时间送达 OpenCV是一个巨大的开源库,广泛用于计算机视觉,人工智能和图像处理领域.它在现实世界中的典型应用是人脸识别,物体检测,人类活动识别,物体跟踪等. 现在,假设我们只需要从整个 ...

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

    图像仿射变换和透视变换 天晴了...... 1.仿射变换 图像的仿射变换就是图像的旋转加上拉升,说直白点,就是把矩形变成平行四边形. 要把矩形变成平行四边行,只需要拉伸其四个角点就行了,事实上,只需要 ...

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

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

  • 基于OpenCV的焊件缺陷检测

    重磅干货,第一时间送达 01. 简介 焊接缺陷是指焊接零件表面出现不规则.不连续的现象.焊接接头的缺陷可能会导致组件报废.维修成本高昂,在工作条件下的组件的性能显着下降,在极端情况下还会导致灾难性故障 ...

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

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

  • 使用OpenCV校准鱼眼镜头

    重磅干货,第一时间送达 01.简介 当我们使用的鱼眼镜头视角大于160°时,OpenCV中用于校准镜头"经典"方法的效果可能就不是和理想了.即使我们仔细遵循OpenCV文档中的步骤 ...

  • python+opencv图像处理(八)

    无所谓,谁会爱上谁... 无所谓,不能天天更... 只要是,不要一直断... -----------------------------------我是可爱的分割线 图像平移的意思就是将图像沿着x轴. ...

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

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

  • 基于OpenCV的手掌检测和手指计数

    重磅干货,第一时间送达 利用余弦定理使用OpenCV-Python实现手指计数与手掌检测. 手检测和手指计数 接下来让我们一起探索以下这个功能是如何实现的. OpenCV OpenCV(开源计算机视觉 ...

  • 基于OpenCV实战:对象跟踪

    重磅干货,第一时间送达 介绍 跟踪对象的基本思想是找到对象的轮廓,基于HSV颜色值. 轮廓:突出显示对象的图像片段.例如,如果将二进制阈值应用于具有(180,255)的图像,则大于180的像素将以白色 ...

  • 基于OpenCV的实战:轮廓检测(附代码解析)

    重磅干货,第一时间送达 利用轮廓检测物体可以看到物体的各种颜色,在这种情况下放置在静态和动态物体上.如果是统计图像,则需要将图像加载到程序中,然后使用OpenCV库,以便跟踪对象. 每当在框架中检测到 ...