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

准备数据集

2020年12月18日

CPOL

4分钟阅读

viewsIcon

7103

downloadIcon

92

在这篇文章中,我们将为我们选择的害虫——驼鹿,创建训练数据集。

引言

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

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

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

上一篇文章中,我们讨论了检测“外来”害虫的方法——那些在大多数预训练DNN模型中未考虑的害虫。我们决定开发和训练我们自己的分类器DNN模型,并将其与运动检测算法结合使用。在这篇文章中,我们将了解如何为我们的DNN分类器准备一个足够的数据集。

足够的数据集

特定数据集是否适合特定DNN模型取决于该模型预期解决的问题。我们将要检测的害虫是驼鹿,我们希望在现实生活中检测这种动物。显然,我们的数据集必须包含许多包含驼鹿的图像。

图像中的动物应该从各个角度和各种姿势拍摄。图像的最小可接受数量取决于DNN模型和所需的精度。通常,深度学习研究人员建议每个对象类别有1000到5000张图像。

为了在现实环境中检测驼鹿,我们应该能够将驼鹿与任何给定帧中可能存在的其他所有物体区分开来。因此,我们需要两个对象类别:驼鹿背景(非驼鹿)。

收集图像

第一步是收集相关的图像。最简单的方法是搜索互联网并保存您找到的图像。这是一个漫长而乏味的过程,但我们需要大量的图像来训练我们自己的DNN模型。

这也是一个重要的教训。数据采集和准备通常是AI项目中最困难的部分。除非您从事前沿研究,否则您可能不会设计新的神经网络架构。如果您没有为要解决的问题准备一个大型、干净的数据集,那么您可以预期将AI项目的70%(甚至更多!)的时间花在这里。

在这种情况下,我们可以通过搜索视频而不是单独的图像来简化和加快此过程。首先,我们搜索并下载包含驼鹿的视频。然后我们从视频文件中提取帧。让我们选择这条路径。

快速搜索会产生一个令人惊讶的大量包含驼鹿的视频列表。以下是一些示例

接下来,我们下载视频文件并使用VLC播放器提取相关的帧。VLC允许您逐帧观看视频,并将任何时间标记的帧上传到磁盘。在我们的例子中,这产生了174张包含驼鹿的图像。以下是一些示例帧

包含驼鹿的帧并不构成用于DNN训练的完整数据集。为了训练分类器,数据集中所有图像的大小必须相同,并且必须在每个图像中完整地看到要分类的对象,例如使用Cascade Trainer GUI。不要忘记我们也需要背景类别的样本。我们可以通过剪掉驼鹿来从相同的帧中获得这些样本。

调整图像大小

由于裁剪后的图像大小可能不同,让我们使用一些自定义的Python代码自动调整它们的大小

import os

class FileUtils:
    @staticmethod
    def get_files(folder):
        files = []
        filenames = os.listdir(folder)
        for (i, fname) in enumerate(filenames):
            fullpath = os.path.join(folder, fname)
            files.append(fullpath)
        return files

import cv2

class Resizer:
    def __init__(self, size):
        self.size = size
        
    def process(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)
            (h, w, c) = img.shape
            if w>h :
                dx = int((w-h)/2)
                img = img[0:h, dx:dx+h]
            else:
                if h>w :
                    dy = int((h-w)/2)
                    img = img[dy:dy+w, 0:w]
            resized = cv2.resize(img, (self.size, self.size), cv2.INTER_AREA)
            f = os.path.basename(fname)
            dfname = os.path.join(dest, f)
            cv2.imwrite(dfname, resized)

该代码使用OpenCV包中的函数从源文件夹加载样本图像,调整它们的大小,并将它们保存到目标目录。请注意,图像调整器只接收一个初始化参数:size

大多数用于图像处理的卷积网络都使用正方形输入图像,因此我们将使我们的调整器将原始图像转换为正方形。调整大小算法考虑到了初始图像可能不是正方形这一事实。为了避免对象变形,算法首先从图像中裁剪居中的正方形片段,然后调整其大小。

现在让我们运行代码并处理图像

source = r"C:\PI_PEST\moose_cropped"
dest = r"C:\PI_PEST\moose_resized"

resizer = Resizer(128)
resizer.process(source, dest)

这为我们提供了数据集的正确大小的样本。

现在我们总共有484个样本:驼鹿类别有200个项目,背景(非驼鹿)对象有284个项目。

后续步骤

484张图像不足以训练我们的DNN以达到高精度。我们可以找到更多视频文件并提取更多帧以增加数据集大小,但有一种更好的方法。在下一篇文章中,我们将看到如何通过数据增强实现相同的结果。

© . All rights reserved.