全文链接:https://tecdat.cn/?p=36968

目标检测作为计算机视觉领域的关键任务之一,在交通管理、智能安防、自动驾驶等众多应用场景中具有重要意义。车牌作为车辆的重要标识,其准确检测对于车辆识别、交通监控等系统的性能提升至关重要。

传统的目标检测方法在面对复杂场景和多样化的车牌样式时,往往存在精度不高、鲁棒性不足等问题。随着深度学习技术的迅速发展,特别是 TensorFlow Keras 框架下的深度学习模型,为解决这些问题提供了强大的工具。

RetinaNet 作为一种先进的深度学习目标检测模型,以其独特的结构和出色的性能,在多个领域取得了显著的成果。本研究将 RetinaNet 模型应用于车牌数据的目标检测,旨在探索其在该特定领域的有效性和潜力。

通过利用大规模的车牌数据集进行训练和优化,期望能够实现对车牌的高精度、快速检测,为相关实际应用提供可靠的技术支持。同时,对模型的性能进行深入分析和评估,为进一步改进和完善车牌检测技术提供有价值的参考。

image.png

image.png

image.png

环境配置与库导入

为了开展本研究,我们首先需要配置Python环境并导入必要的库。这些库涵盖了数据处理、模型构建、可视化以及深度学习框架等多个方面。

我们利用pandas库来处理和分析数据集,numpy库用于高效的数值计算。可视化方面,我们引入了matplotlibseaborn库来绘制图表,以便直观地展示数据特征和模型结果。此外,通过%matplotlib inline%config InlineBackend.figure_format='retina'的设置,我们确保了在Jupyter Notebook环境中图表的高质量显示。

为了构建和训练深度学习模型,我们采用了TensorFlow框架及其高级API Keras。特别地,针对目标检测任务,我们集成了keras_retinanet库,该库提供了基于RetinaNet架构的预训练模型和工具。

数据集准备与预处理

首先,我们使用pandas库从indian_number_plates.json文件中读取车牌数据。该JSON文件以行格式存储,每行代表一个包含车牌图像URL及其标注信息的记录。通过调用pd.read_json函数,并设置lines=True参数,我们成功地将这些数据加载到DataFrame对象plates_df中。

接下来,为了确保存储下载图像的目录存在,我们使用os.makedirs函数创建了一个名为number_plates的目录。如果该目录已存在,则通过设置exist_ok=True参数避免抛出错误。

为了构建可用于模型训练的数据集,我们初始化了一个空字典dataset,其中包含用于存储图像名称、边界框坐标(x_miny_minx_maxy_max)和类别名称(class_name)的列表。然后,我们遍历plates_df中的每一行,对每条记录执行以下操作:

  1. 使用urllib.request.urlopen函数根据记录中的content字段(即图像URL)下载车牌图像。
  2. 将下载的图像对象转换为PIL图像,并转换为RGB颜色模式以匹配常见的图像处理需求。
  3. 将处理后的图像保存到number_plates目录下,文件名格式为licensed_car_{counter}.jpeg,其中counter用于追踪已下载图像的数量。
  4. 将图像的存储路径添加到dataset["image_name"]列表中。
  5. 解析记录中的annotation字段,提取车牌边界框的坐标信息。根据图像的实际宽度和高度,将标注中的相对坐标转换为绝对像素坐标,并存储到相应的列表中。
  6. 将车牌的类别名称(在本例中为"license_plate")添加到dataset["class_name"]列表中。

完成上述遍历后,我们打印出已下载的汽车图像数量,以确认数据集的完整性和规模。


print("Downloaded {} car images.".format(counter))

通过上述步骤,我们成功地从JSON文件中提取并整理了车牌图像及其标注信息,构建了一个完整的数据集,为后续的目标检测模型训练提供了有力的支持。

image.png

数据预处理与初步探索

在数据处理的初步阶段,我们首先利用Pandas库将数据集加载为一个DataFrame对象,以便进行后续的分析与操作。以下是加载数据集并查看其前几行数据的代码实现:

df = pd.DataFrame(dataset)
df.head()

image.png

此步骤不仅验证了数据成功加载,还通过head()方法提供了数据集的概览,有助于初步了解数据的结构和内容。

图像对象可视化函数

为了更直观地展示数据集中的图像及其包含的特定对象(如通过边界框标记的对象),我们定义了一个名为show_image_objects的函数。该函数接收DataFrame中的一行数据作为输入,该数据行包含图像路径和对象边界框的坐标信息。

示例应用

为了演示show_image_objects函数的功能,我们可以从DataFrame中选取一行数据作为示例,并调用该函数来展示图像及其包含的边界框:

show_image_objects(df.iloc[0])

通过上述步骤,我们不仅能够展示数据集中的图像,还能直观地看到图像中特定对象的边界框:

image.png

image.png

数据预处理

在数据准备阶段,为了有效地训练模型并评估其性能,我们首先将数据集划分为训练集和测试集。这通过train_test_split函数实现,该函数从sklearn.model_selection模块中导入,用于随机分割数据集。具体地,我们将原始数据集df按照80%训练集和20%测试集的比例进行划分,并设置随机种子RANDOM_SEED以确保结果的可重复性。

train_df, test_df = train_test_split(
  df, 
  test_size=0.2, 
  random_state=RANDOM_SEED
)

接下来,为了后续训练过程中的便利,我们将训练集的注释信息(即标注数据)保存至annotations.csv文件中,并去除索引和表头信息以简化文件结构。同时,我们定义了一个包含所有类别名称的集合classes,在这个例子中仅包含'license_plate'一个类别。然后,我们将这些类别名称及其对应的索引(从0开始)写入classes.csv文件,该文件用于模型训练时指定类别标签。

最后,为了验证上述步骤是否按预期执行,我们使用!head命令(通常在Jupyter Notebook或类似环境中可用)来查看classes.csvannotations.csv文件的前几行内容。这有助于快速检查文件内容是否符合预期格式,从而确保后续处理流程的顺利进行。

image.png

训练

这段代码主要是进行了模型的下载和训练操作。

首先,定义了一个预训练模型的路径 PRETRAINED_MODEL ,并指定了一个模型的 URL URL_MODEL 。然后,使用 urllib.request.urlretrieve 函数从指定的 URL 下载模型,并保存到指定的路径。

最后,通过执行 keras_retinanet/bin/train.py 脚本来进行模型的训练。其中,--freeze-backbone 表示冻结骨干网络,--random-transform 可能是用于数据增强的随机变换,--weights {PRETRAINED_MODEL} 指定了使用刚刚下载的预训练模型的权重,--batch-size 8 设定了批处理大小为 8,--steps 500 可能是每个 epoch 中的训练步数,--epochs 10 设定了训练的轮数为 10 ,并使用 csv annotations.csv classes.csv 来指定数据的相关文件。

image.png

image.png

加载训练模型

image.png

首先,确定模型的路径。然后,加载模型。

例如,如果 CLASSES_FILE 中的内容为 0,cat\n1,dog\n2,rabbit ,那么 labels_to_names 字典可能为 {0: 'cat', 1: 'dog', 2: 'rabbit'} 。这种方式能够方便地将模型预测的类别标签转换为对应的名称,从而提高模型结果的可读性和可理解性。

image.png

预测

设置了分数阈值:
并定义了根据检测结果在图像上绘制框和标注的函数:

还定义了展示检测到的物体的函数:


  plt.axis('off')
  plt.imshow(draw)
  plt.show()

最后,查看测试数据框的前 10 行:

例如,假设一张图像中有一个物体被标注为“cat”,其预测分数为 0.8 ,且超过了阈值 0.6 。那么在图像上将会绘制出一个框,并标注“cat 0.800”。又如,对于另一张图像,如果多个物体的预测分数都高于阈值,将会相应地绘制多个框和标注。

image.png

展示检测结果

通过以下代码对测试数据集中的前三个样本进行检测结果的展示:

image.png

image.png

image.png

blogpost-hero_1536x864.jpg


拓端tecdat
195 声望46 粉丝