65.9K
CodeProject 正在变化。 阅读更多。
Home

使用数据增强扩展数据集

2020年12月21日

CPOL

4分钟阅读

viewsIcon

7942

downloadIcon

110

在本文中,我们将了解如何通过数据增强实现相同的结果。

引言

不受控制的野生动物对于企业和房主来说都是一个难题。像鹿、驼鹿甚至猫这样的动物都会对花园、庄稼和财产造成破坏。

在本系列文章中,我们将演示如何在树莓派上实时(或近乎实时)检测害虫(例如麋鹿),然后采取行动将其清除。由于我们不想造成任何伤害,我们将专注于通过播放响亮的声音来吓跑害虫。

欢迎您下载项目的源代码。我们假设您熟悉 Python,并对神经网络的工作原理有基本了解。

上一篇文章中,我们准备了麋鹿分类数据集的初始版本。它包含 200 个“麋鹿”类别的样本和 284 个“背景”类别的样本。是不是有点小?在本文中,我们将演示如何在不收集新图像的情况下增强我们的数据集。

数据增强

数据增强通过各种图像修改从现有图像派生新样本。其中最常见的有几何变换、色彩空间变换、数据加噪和图像滤波。在应用数据增强算法时,我们应确保图像修改适合我们的数据集,并且不会损害样本。

让我们考虑一下我们的麋鹿数据集。哪种修改类型适用于它?

色彩空间变换和数据加噪无效。颜色是动物分类的重要特征,因此我们不应更改样本图像的色彩空间。数据加噪是包含手写数字或符号的数据集的有效技术。我们不期望这对自然栖息地中的麋鹿图像有用。

剩下的是几何变换和图像滤波。我们将在 Python 中实现它们时详细讨论这些。

几何变换

有许多几何变换可用于图像数据增强:翻转、旋转、缩放、裁剪、平移等。

一个明显且非常有用的变换是水平翻转,它相对于垂直轴镜像图像。

另一个流行的几何变换是旋转,它模拟从不同角度观察样本。请注意,此变换仅应应用适度的旋转角度以保留物体形状。

我们可以使用 Python OpenCV 软件包轻松实现几何变换

class FlipProcessor:
    def name(self):
        return "flip"
        
    def process(self, image):
        return cv2.flip(image, 1)
    
class RotateProcessor:
    def __init__(self, angle, scale):
        self.angle = angle
        self.scale = scale
        
    def name(self):
        if self.angle>0:
            sa = str(self.angle)
        else:
            sa = "_"+str(-self.angle)
        return "rotate"+sa
        
    def process(self, image):
        (h, w, c) = image.shape
        center = (w/2, h/2)

        rmat = cv2.getRotationMatrix2D(center, self.angle, self.scale)
        rotated = cv2.warpAffine(image, rmat, (w, h))

        return rotated

图像过滤

图像滤波是一种有用但不太直观的数据增强类型。很难估计哪些滤波器可以从现有图像生成最有用的数据样本。

我们的数据集由从野生动物视频中提取的帧组成,因此可以合理地假设有些帧清晰,有些帧模糊。因此,锐化和模糊帧可以改进和多样化我们的数据集。这是 Python 代码中的实现方式

class SmoothProcessor:
    def __init__(self, filter_size):
        self.filter_size = filter_size
        
    def name(self):
        return "smooth"+str(self.filter_size)
        
    def process(self, image):
        smoothed = cv2.GaussianBlur(image,(self.filter_size, self.filter_size),0)

        return smoothed

class SharpenProcessor:
    def __init__(self, filter_size):
        self.filter_size = filter_size
        
    def name(self):
        return "sharpen"+str(self.filter_size)
        
    def process(self, image):
        sharpen = cv2.bilateralFilter(image, self.filter_size, 150, 150);

        return sharpen

我们还需要一个将原始图像复制过来的变换(稍后我们将解释其原因)

class OriginalProcessor:        
    def name(self):
        return ""
        
    def process(self, image):
        return image

现在所有技巧都在一个算法中

现在我们有了所有要使用的变换。这是将自动处理所有图像并通过变换的算法

class Augmentor:
    def __init__(self, processors):
        self.processors = processors

    def generate(self, source, dest):
        files = FileUtils.get_files(source)
        if not os.path.isdir(dest):
            os.mkdir(dest)
        for (i, fname) in enumerate(files):
            img = cv2.imread(fname)
            for (j, proc) in enumerate(self.processors):
                p_img = proc.process(img)
                f = os.path.basename(fname)
                f = os.path.splitext(f)[0]
                f = f + proc.name() + ".png"
                dfname = os.path.join(dest, f)
                cv2.imwrite(dfname, p_img)

generate 方法遍历源文件夹中的文件,对它们应用所有指定的变换,并将修改后的图像保存到目标目录,文件名为新名称(原始名称后附加处理器名称)。

我们可以使用以下代码将增强算法应用于我们的样本图像

folder = r"C:\PI_PEST\moose"
gen_folder = r"C:\PI_PEST\moose_gen"

processors = [OriginalProcessor(), FlipProcessor()]
gen = Augmentor(processors)
gen.generate(folder, gen_folder)

processors = [SmoothProcessor(5), SharpenProcessor(5)]
gen = Augmentor(processors)
gen.generate(gen_folder, gen_folder)

processors = [RotateProcessor(15, 1.2), RotateProcessor(-15, 1.2)]
gen = Augmentator(processors)
gen.generate(gen_folder, gen_folder)

请注意我们是如何分三个顺序步骤实现增强的。

首先,我们应用了翻转和“原始”处理器。现在我们知道为什么 OriginalProcessor 只是按原样复制原始图像:在此步骤之后,我们希望将原始图像和翻转图像的副本都放入 moose_gen 文件夹。

在第二步中,我们将平滑和锐化处理器应用于第一步生成的所有图像。

在最后一步中,我们将两个变换(顺时针和逆时针旋转 15 度)应用于前两步生成的所有图像。样本的最终图像如下所示

后续步骤

我们现在有多少样本?我们有 18 倍!

我们有 3600 个“麋鹿”类别的样本和 5112 个“背景”类别的样本。对于我们的目的来说,这个大小的数据集将提供可接受的麋鹿检测结果。

但是,如果您正在开发商业害虫探测器,您会想要一个大得多的数据集。在处理 AI 项目时,您会遇到的一个普遍主题是获取高质量数据是最困难的任务。

对于许多常见类型的问题,都有成熟、经过实战检验的 DNN 架构,但获取大量图像、清理它们并增强它们可能需要数天、数周甚至数月,具体取决于您正在解决的问题的大小。

下一篇文章中,我们将讨论使用增强数据集训练我们的 DNN 分类器。

© . All rights reserved.