进行图像增广(数据扩充)的15种功能总结和Python代码实现(一)

简介: 进行图像增广(数据扩充)的15种功能总结和Python代码实现

python代码可以自己扩充图像数据集。

640.png

无论我们喜欢Keras还是Pytorch,我们都可以使用丰富的资料库来有效地增广我们的图像。但是如果遇到特殊情况:

  • 我们的数据集结构复杂(例如3个输入图像和1-2个分段输出)。
  • 我们需要完全的自由透明度
  • 我们希望进行这些库未提供的扩充方法。

对于这些情况以及其他特殊情况,我们必须能够掌握我们自己的图像增广函数。而且,我每次都使用自己的函数。因此,在本文中,我将介绍并提供执行图像增广的功能。

640.png

我将使用朋友的照片来提醒我在加拿大度过的美好时光作为示例。希望您喜欢这张照片,因为这是您在本文中看到的唯一一张照片。

我将增广过程细分为一个实际的案例,将我们的函数与图像和目标图像一起使用。这将使您对将要描述的方法的灵活性有所了解:

  • 翻转
  • 裁剪
  • 过滤和锐化
  • 模糊
  • 旋转,平移,剪切,缩放
  • 剪下
  • 色彩
  • 亮度
  • 对比
  • 均匀和高斯噪声
  • 渐变
  • 镜头变形

本文的目的不是为了证明增广技术是如何设计的,而是理解它们的用法。

一些有用的函数

在开始之前,我想解释每种方法具有的通用结构。它实际上是一个要初始化的对象。该对象将以我们的样本作为参数调用,并将返回我们的扩充样本。这就是全部?是的,仅此而已!然后,让我们从增广功能之前的一些有用函数开始。

Resize

640.png

第一个有用的函数允许我们使用(宽度,高度)形状调整图像大小。这个使我们看到了所有其他的初始化方式。我们实例化一个对象,该对象的大小被参数化。在我们的例子中,所有样本(图像和目标)将以相同的尺寸返回。使用此类型的功能,我们可以轻松地以所需方式处理图像和目标。

class Resize(object):
   def __init__(self, output_size):
       self.output_size = output_size
   def __call__(self, X, Y):
       _X = cv2.resize(X, self.output_size)
       w, h = self.output_size
       c = Y.shape[-1]
       _Y = np.zeros((h, w, c))
       for i in range(Y.shape[-1]):
           _Y[..., i] = cv2.resize(Y[..., i], self.output_size)
       return _X, _Y

Clip

剪辑函数是一项非常有用的函数,尤其是当您需要从一种颜色空间切换到另一种颜色空间或在0和1或0和255之间重置图像时。

640.png

默认情况下,如果仅指定一个阈值,则最小阈值为0。

class Clip(object):
   def __init__(self, mini, maxi=None):
       if maxi is None:
           self.mini, self.maxi = 0, mini
       else:
           self.mini, self.maxi = mini, maxi
   def __call__(self, X, Y):
       mini_mask = np.where(X < self.mini)
       maxi_mask = np.where(X > self.maxi)
       X[mini_mask] = self.mini
       X[maxi_mask] = self.maxi
       return X, Y

Normalize or Standardize

在传递模型中的输入之前,我们通常希望对数据进行标准化规范化。当然,这些操作可以在特定的上完成。

640.png

默认情况下,对整个图像执行标准化和规范化。

class Normalize(object):
   def __init__(self, axis=None):
       self.axis = axis
   def __call__(self, X, Y):
       mini = np.min(X, self.axis)
       maxi = np.max(X, self.axis)
       X = (X - mini) / (maxi - mini)
       return X, Y
class Standardize(object):
   def __init__(self, axis=None):
       self.axis = axis
   def __call__(self, X, Y):
       mean =  np.mean(X, self.axis)
       std = np.std(X, self.axis)
       X = (X - mean) / std
       return X, Y

ToTensor

最后,如果您使用的是Pytorch,则需要将图像转换为Torch.Tensor。唯一需要注意的是,使用Pytorch,我们的图像维度中首先是通道,而不是最后是通道。最后,我们还可以选择张量的输出类型

class ToTensor(object):
   def __init__(self, X_type=None, Y_type=None):
       # must bu torch types
       self.X_type = X_type
       self.Y_type = Y_type
   def __call__(self, X, Y):
       # swap color axis because
       # numpy img_shape: H x W x C
       # torch img_shape: C X H X W
       X = X.transpose((2, 0, 1))
       Y = Y.transpose((2, 0, 1))
       # convert to tensor
       X = torch.from_numpy(X)
       Y = torch.from_numpy(Y)
       if self.X_type is not None:
           X = X.type(self.X_type)
       if self.Y_type is not None:
           Y = Y.type(self.Y_type)
       return X, Y

怎么使用?

我们要做的就是定义我们要在样本中进行的转换的列表,仅此而已。之后我们什么也别碰。请注意,转换顺序很重要。而且由你决定

X, Y = get_next_sample()
   for t in transform: # data augmentation
       X, Y = t(X, Y)
   pred = model.predict(X, Y)

现在,我们可以深入研究本文的目的,并查看图像增广技术。

旋转

640.gif

第一个,也是最简单的一个,包括在图像的水平垂直轴上随机执行翻转。换句话说,执行垂直翻转的机会为50/100,执行水平翻转的机会为50/100。

class Flip(object):
   def __call__(self, X, Y):
       for axis in [0, 1]:
           if np.random.rand(1) < 0.5:
               X = np.flip(X, axis)
               Y = np.flip(Y, axis)
       return X, Y

裁剪

要进行图像增广,通常会随机裁剪图像。换句话说,我们在随机区域上裁剪了一部分随机大小的图像。

640.gif

可以从尺寸的比例(高度,宽度)中选择裁剪图像的尺寸。如果未指定裁剪的比例最大大小,则默认情况下,我们将认为它是图像的大小。

class Crop(object):
   def __init__(self, min_size_ratio, max_size_ratio=(1, 1)):
       self.min_size_ratio = np.array(list(min_size_ratio))
       self.max_size_ratio = np.array(list(max_size_ratio))
   def __call__(self, X, Y):
       size = np.array(X.shape[:2])
       mini = self.min_size_ratio * size
       maxi = self.max_size_ratio * size
       # random size
       h = np.random.randint(mini[0], maxi[0])
       w = np.random.randint(mini[1], maxi[1])
       # random place
       shift_h = np.random.randint(0, size[0] - h)
       shift_w = np.random.randint(0, size[1] - w)
       X = X[shift_h:shift_h+h, shift_w:shift_w+w]
       Y = Y[shift_h:shift_h+h, shift_w:shift_w+w]
       return X, Y
目录
相关文章
|
1天前
|
数据采集 JSON API
【2024-简洁版】python爬虫 批量查询自己所有CSDN文章的质量分:方便快速上手修改代码
【2024-简洁版】python爬虫 批量查询自己所有CSDN文章的质量分:方便快速上手修改代码
8 0
|
2天前
|
XML 前端开发 数据格式
BeautifulSoup 是一个 Python 库,用于从 HTML 和 XML 文件中提取数据
BeautifulSoup 是 Python 的一个库,用于解析 HTML 和 XML 文件,即使在格式不规范的情况下也能有效工作。通过创建 BeautifulSoup 对象并使用方法如 find_all 和 get,可以方便地提取和查找文档中的信息。以下是一段示例代码,展示如何安装库、解析 HTML 数据以及打印段落、链接和特定类名的元素。BeautifulSoup 还支持更复杂的查询和文档修改功能。
9 1
|
2天前
|
Python
Python中的装饰器:提升代码可读性与复用性
Python中的装饰器是一种强大的工具,能够提升代码的可读性和复用性。本文将深入探讨装饰器的原理、用法以及在实际项目中的应用,帮助读者更好地理解和利用这一特性,提升代码质量和开发效率。
|
3天前
|
监控 Python
Python中的装饰器:提升代码可读性与可维护性
Python中的装饰器是一种强大的工具,可以在不修改函数源代码的情况下,增加新的功能。本文将介绍装饰器的基本概念,以及如何使用装饰器来提升代码的可读性和可维护性。通过实例演示,读者将了解装饰器在各种场景下的灵活运用,从而更好地理解并应用于实际开发中。
|
3天前
|
缓存 Python
Python中的装饰器:提升代码可读性与灵活性
在Python编程中,装饰器是一种强大的工具,可以通过在函数或方法周围包装额外的功能来提升代码的可读性和灵活性。本文将深入探讨装饰器的概念、用法和实际应用,帮助读者更好地理解并运用这一Python编程的利器。
|
3天前
|
存储 JSON 数据挖掘
python序列化和结构化数据详解
python序列化和结构化数据详解
12 0
|
4天前
|
数据采集 数据可视化 数据挖掘
Python 与 PySpark数据分析实战指南:解锁数据洞见
Python 与 PySpark数据分析实战指南:解锁数据洞见
|
4天前
|
IDE Java 开发工具
讨论 Python 中泛型(或类似泛型的功能)的优点和缺点
Python虽无显式泛型系统,但可通过类型注解和工具实现类似功能。优点包括提升代码可读性、静态类型检查、更好的IDE支持、灵活性和可逐渐引入。缺点涉及运行时性能开销、学习成本、非强制性及与旧代码集成问题。适当使用工具和实践可管理这些挑战。
15 2
|
4天前
|
缓存 并行计算 Serverless
优化Python代码性能的5个技巧
在日常Python编程中,代码性能的优化是一个重要的议题。本文介绍了5个实用的技巧,帮助你提高Python代码的执行效率,包括使用适当的数据结构、优化循环结构、利用内置函数、使用生成器表达式以及并行化处理。通过这些技巧,你可以更高效地编写Python代码,提升程序的性能和响应速度。
|
Python
使用python实现一个文件搜索功能,类似于Everything功能
一般人日常总是会将一些片段信息记录到文件中,放到电脑硬盘上。等过段时间,可能就不知道放到哪里了,电脑上文件夹太多。 找文件一般都会借助于搜索软件,比如Everything软件就很强大,输入名称,就能全局查找文件;
393 0