图像生成技术 | 巧妙用于目标检测任务

点击下方卡片,关注“小白玩转Python”公众号

在深度学习中,缺乏足够的训练数据是一个主要问题。对于计算机视觉任务,一个有前景的解决方案是自动生成带注释的合成图像。

在本文中,我将首先概述一些用于生成合成图像数据的技术。然后,我们将生成一个不需要手动注释的训练数据集,并使用它来训练一个Faster R-CNN目标检测模型。最后,我们将在真实图像上测试我们训练好的模型。

图像生成技术

理论上,合成图像是完美的。你可以生成几乎无限数量的图像,而无需任何手动标注。使用真实图像和手动标注的训练数据集可能包含大量的人为标注错误,并且它们往往是不平衡的数据集,带有偏差(例如,汽车的图像很可能是从侧面或前面拍摄的,并且是在道路上)。

然而,合成图像存在一个叫做仿真到现实域差距的问题。仿真到现实域差距源于这样一个事实:我们使用合成训练图像,但希望在实际部署时在真实世界图像上使用我们的模型。

有几种不同的图像生成技术试图缩小这个域差距。

剪切与粘贴

生成合成训练图像的最简单方法之一是剪切与粘贴方法。如下图所示,这种技术需要一些真实图像,从中将要识别的对象剪切出来。然后,这些对象可以粘贴到随机背景图像上,以生成大量新的训练图像。

956c8540c0bb900073ee7e634a36d796.png生成附加的合成训练图像,剪切一些真实的对象样本,然后将它们粘贴到背景图像上。图像来源于Dwibedi、Misra和Hebert【1】

虽然Georgakis等人【2】认为这些对象的位置应该是现实的,以获得更好的结果(例如,对象应该放在支撑面上,如台面、桌子或地板),Dwibedi等人通过让对象在场景中飞来飞去也取得了不错的结果。

这种方法的一个缺点是我们受限于真实对象的分割图像。为了获得多样化的数据,我们需要从不同角度拍摄的图像,并且我们不能在后期更改对象的亮度。

写实主义

另一种方法是尽可能逼真地渲染图像。这意味着使用高质量的3D模型和纹理,计算密集的渲染引擎来模拟逼真的光照,以及物理模拟来放置对象。下图来自Hodaň等人【3】展示了用于生成合成训练图像的两个写实的3D环境。

aae0d4bb65ef29b5d9d6d87e9ffd0f0e.png写实的3D环境用于渲染合成训练图像。图像来源于Hodaň等人【3】

这种方法的限制在于创建这些高质量3D环境和3D对象所需的时间、精力和技能。

域随机化

域随机化的思想是使虚拟训练环境尽可能随机化。因为每个生成的训练图像都是不同的,所以真实世界的图像看起来只是我们训练数据的另一种变化。Tobin等人【4】是最早使用这一概念生成合成训练图像的人之一。他们在模拟环境中随机化了以下参数以生成多样的数据:

  • 干扰对象的数量和形状

  • 所有对象的位置和纹理

  • 虚拟相机的位置、方向和视场

  • 场景中的灯光数量及其位置、方向和反射特性

  • 添加到图像中的随机噪声的类型和数量

398944f17da5b35f57314e0afef1e13b.png

域随机化通过随机化大量参数来生成多样的训练图像。图像来源于Tobin等人【4】

由于对象的纹理和颜色通常是随机的,计算机视觉模型必须主要依靠对象的形状进行学习。这意味着由于强随机化,许多有用的信息可能会丢失。

使用Blender和Python创建合成目标检测数据集

现在我们对不同的方法有了一个大致的了解,让我们使用Blender生成图像。Blender是一款非常流行的免费开源软件。它有一个名为Cycles的渲染引擎,我们可以用它来生成3D模型的写实渲染图像。它还有一个Python API,我们可以用它自动生成大量图像,包括每个图像的注释。

安装Blender

首先,从download.blender.org/release下载Blender 2.93.18版本(LTS)。

在Linux上,下载并解压blender-2.93.18-linux-x64.tar.xz到你选择的文件夹,例如~/synth-data/blender-2.93.18-linux-x64。对于Windows,使用blender-2.93.18-windows-x64.zip。Blender 3.3.16似乎也能正常工作,但更新版本在我的电脑上似乎无法正常工作。

你可以在终端中通过输入~/synth-data/blender-2.93.18-linux-x64/blender打开Blender。这应该会打开Blender的启动屏幕。我们的想法是渲染虚拟相机看到的图像。

3ba54aa1b343d37bd198e7eda0f7d759.png

Blender的默认启动屏幕。中间是活动工作区,上部可以切换到不同模式,右上是我们的场景对象,右下是属性

blender-gen

为了使用Blender和Python API自动生成训练图像和边界框注释,我使用了一个开源工具blender-gen。我专门为研究目的创建了blender-gen,以尝试不同的功能【5】。

将仓库克隆到你选择的文件夹,例如~/synth-data/blender-gen。为了测试一切是否正常运行,让我们测试一下。以下命令将在后台模式下启动Blender并运行Python脚本main.py。

cd ~/synth-data/blender-gen
~/synth-data/blender-2.93.18-linux-x64/blender --background --python main.py

几秒钟后,你应该在文件夹~/synth-data/blender-gen/DATASET/Suzanne/images/中看到用Blender的猴子对象Suzanne和一些干扰立方体渲染的样本JPG图像。在本教程中,我们将生成用于苹果检测模型的训练图像。

3D模型

首先,我们需要检测对象的主要3D模型。你可以从ambientCG.com和polyhaven.com下载免费使用并受Creative Commons CC0 1.0 Universal License许可的资源。作为我们的目标对象,例如从ambientCG下载3DApple001_LQ-1K-PNG.zip,并将所有文件解压到文件夹~/synth-data/blender-gen/models/Apple/。

96043b1264b8f2a6a073a4efc017d9b7.png

3D Apple 001模型来自ambientCG.com

作为附加干扰对象,我使用了如下所示的鳄梨、柠檬和梨模型,并将这些文件分别解压到~/synth-data/blender-gen/distractors/Avocado,/.../Lemon,和/.../Pear中。

干扰对象用于混淆深度学习模型,使其不仅仅学会识别渲染的前景对象。当它们放置在我们的主要3D模型前面时,也会增加遮挡。

131de25df4e31872d1033ef98ec40ec2.jpeg

干扰对象:3D Lemon 001、3D Avocado 001和3D Pear 002来自ambientCG.com

随机图像用作我们渲染3D模型的背景。你可以使用任何你喜欢的图像。我总是使用COCO图像数据集。具体来说,我使用2017年的验证图像集,它包含5000张图像。将所有背景图像放入文件夹~/synth-data/blender-gen/bg/。

HDR图像亮度

接下来是亮度。可以通过创建点光源并指定其数量、位置、强度和颜色来手动设置亮度。一种更简单的方法是使用高动态范围(HDR)图像的基于图像的亮度。使用基于图像的亮度,光源来自真实场景的3D图像。

前往ambientCG.com或polyhaven.com,下载一些*.exr或*.hdr文件,并将它们放入文件夹~/synth-data/blender-gen/environment/。

3149e5face0255da507005ef1dd5f069.png

HDR图像用于写实的基于图像的亮度

HDR图像提供了真实的亮度和反射,生成我们3D模型的写实渲染图像。通过改变HDRI发光强度,我们可以控制光照的强度,从而控制3D模型的亮度。

c94f551f67afb067b33443ca3492147e.jpeg

配置

配置只需简单地编辑 config.py 文件。从初始的 config.py 开始,打开并编辑以下几行:

self.out_folder = 'Apple'
self.model_paths = ['./models/Apple/3DApple001_LQ-1K-PNG.obj']
self.distractor_paths = ['./distractors/Lemon', './distractors/Pear', './distractors/Avocado']
self.object_texture_path = '' # use default texture
self.distractor_texture_path = '' # use default textures
self.cam_rmin = 0.15 # minimum camera distance
self.cam_rmax = 0.8  # maximum camera distance
self.resolution_x = 640  # output image width
self.resolution_y = 360  # output image height
self.number_of_renders = 1  # number of rendered images

然后运行:

cd ~/synth-data/blender-gen
~/synth-data/blender-2.93.18-linux-x64/blender --python main.py

这将使 Blender 创建一个包含我们的苹果 3D 模型、一些干扰物体、虚拟相机、HDRI 照明和随机背景图像的 3D 场景。

c6587da3d0154686c3d22a85a9f65434.jpeg

Blender 工作流程的图片:左侧是 Blender 中的 3D 场景,包含虚拟相机和我们的 3D 物体。右侧是包含随机背景图像的渲染图像

相机在 3D 场景中使用球面坐标的径向距离、倾斜角和方位角进行放置。每个参数都有最小值和最大值。在每次渲染时,参数在给定的区间内随机采样。相机的 cam_rmin 和 cam_rmax 距离定义了图像中物体的大小。

生成的合成图像和标注运行以下命令将快速可视化生成的边界框:

python show_annotations.py

ea2655578298f0d9a5fd099220893254.jpeg

可视化的渲染图像中,边界框标注为绿色矩形

生成的图像存储在文件夹 ~/synth-data/blender-gen/DATASET/Apple/images 中。标注文件存储在 ~/synth-data/blender-gen/DATASET/Apple/annotations/instances_default.json 中。如果我们打开标注文件,可以看到每个图像的边界框(bbox)标注,格式为 Microsoft COCO 数据格式:

{
  "images": [
    {
      "id": 0,
      "file_name": "000000.jpg",
      "height": 360,
      "width": 640
    }
  ],
  "annotations": [
    {
      "id": 0,
      "image_id": 0,
      "bbox": [
        470.81,
        201.34,
        79.22,
        68.45
      ],
      "category_id": 1,
      "segmentation": [],
      "iscrowd": 0,
      "area": 5423.04,
      "keypoints": [],
      "num_keypoints": 0
    }
  ],
  "categories": [
    {
      "supercategory": "",
      "id": 1,
      "name": "Apple",
      "skeleton": [],
      "keypoints": []
    }
  ]
}

现在是时候生成一个更大的数据集了。在 config.py 文件中,将以下行更改为训练样本的数量:

self.number_of_renders = 2000

然后运行 Blender:

cd ~/synth-data/blender-gen
~/synth-data/blender-2.93.18-linux-x64/blender --background --python main.py

使用这个由2000张640x360的jpg图像组成的合成训练数据集,我们现在可以训练一个我们选择的目标检测模型。

训练和测试一个在真实数据上的目标检测模型

现在我们有了包含图像和COCO数据格式边界框标注的合成数据集,我们可以训练一个目标检测模型。为了验证,我用不同的随机种子生成了额外的100张图像。

模型训练

有关模型训练的部分,此处不做详细介绍,感兴趣的小伙伴可以通过下面链接查看训练源码:https://github.com/leoneversberg/object-detection-pytorch。代码介绍如何使用blender-gen创建的合成玩具数据集在PyTorch中训练Faster R-CNN模型,并使用2000个合成训练样本,采用随机梯度下降(SGD)和0.00001的学习率训练了我的模型12个epoch。

一个图表显示了12个周期中的损失下降。训练损失和验证损失都在下降,并在第11个周期后趋于平稳,表明训练完成。

0941ec91e65dac1442798a9fa949b24f.jpeg使用100%合成训练和验证图像训练的Faster R-CNN苹果目标检测模型

在GeForce RTX 3060 GPU上训练我的苹果目标检测模型(Faster R-CNN与MobileNet骨干)12个周期大约花了20分钟。之后,训练和验证损失趋于平稳,这意味着模型训练完成了。让我们看看在随机选择的合成验证图像上的推理结果。

281eca2db91d3331266109f6d8d3c9bf.jpeg一张图像显示了模型在合成验证图像上的推理结果。红色矩形显示了围绕苹果的精确边界框标注,表明模型已经学会了检测苹果

在真实图像上的模型测试

最后,让我们在我用智能手机拍摄的未见过的测试图像上测试我们的模型。

f81c9357b58168adaf58490b3fa34076.jpeg三张从不同角度拍摄的桌上水果和物体的真实测试图像。在所有测试图像中,模型都能正确检测到苹果

尽管模型在训练过程中没有见过任何真实图像,这意味着存在sim-to-real域间差距,但模型仍能准确检测到苹果。

结论

在本文中,我们介绍了生成合成训练图像的三种不同技术:剪切粘贴、照片写实和域随机化。

在逐步教程中,我们使用Blender和blender-gen生成了合成训练图像。使用这些数据,我们可以在没有任何手动标注工作的情况下训练一个目标检测模型。

在本教程中,我使用了一个免费的苹果3D模型作为示例。但是,您可以使用任何您喜欢的3D模型来生成合成图像,然后训练另一个目标检测模型。

如果sim-to-real域间差距太大,导致在真实测试图像上的表现不够好,我发现对基础合成模型进行少量真实图像训练集的微调效果很好。

文中提及参考资料

[1] D. Dwibedi, I. Misra, M. Hebert, Cut, Paste and Learn: Surprisingly Easy Synthesis for Instance Detection (2017), IEEE International Conference on Computer Vision (ICCV)

[2] G. Georgakis, A. Mousavian, A. C. Berg, J. Kosecka, Synthesizing Training Data for Object Detection in Indoor Scenes (2017), Robotics: Science and Systems XIII

[3] T. Hodaň et al., Photorealistic Image Synthesis for Object Instance Detection (2019), IEEE International Conference on Image Processing (ICIP)

[4] J. Tobin et al., Domain Randomization for Transferring Deep Neural Networks from Simulation to the Real World (2017), IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)

[5] L. Eversberg, J. Lambrecht, Generating Images with Physics-Based Rendering for an Industrial Object Detection Task: Realism versus Domain Randomization (2021), MDPI Sensors 21 (23)

·  END  ·

HAPPY LIFE

7eba8fbc5e8d02b1082b0284dc12f3cf.png

本文仅供学习交流使用,如有侵权请联系作者删除

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值