在计算机视觉领域,手动标注大量图像数据不仅耗时,而且容易出错,有时甚至显得乏味。为了提高效率,可能需要一种更快更有效的方法。这时,合成数据的优势就显现出来了。合成数据是通过增强和修改现有数据生成的。使用合成数据来训练计算机视觉模型,相较于手动标注的数据,有诸多优势,比如能够几乎瞬间生成大量多样化且成本效益高的数据,同时避免了人类标注者可能引入的错误。将合成数据添加到项目中,可以增强模型的泛化能力,学习想在图像中识别的特征。
本文将展示如何创建涉及随机电路的合成数据,以训练一个能够检测面包板上电阻和导线的计算机视觉模型。首先,需要创建一个计算机视觉模型,能够检测电路组件。首先用iPhone拍摄了电阻的视频,并将它们上传到Roboflow,以便将视频分割成多个图像进行手动标注。
在慢慢积累数据集并训练了几个版本的模型后,有了数百张图像。每张图像最初都需要手动标注,但在训练了第一个模型之后,可以使用Roboflow的Label Assist来协助。尽管如此,检查每张图像、进行小的调整和纠正错误仍然可能变得乏味。这时,合成数据就派上用场了。
合成数据可以与真实图像一起使用,或者完全替代真实图像。如果有一个希望计算机视觉模型检测的对象的3D资产,可以轻松地创建合成数据,而不是拍摄数百张照片。获取了一些便宜的面包板、电阻和一些导线的3D模型。然后,按照Unity Perception教程生成合成数据。使用了内置的TextureRandomizer和RotationRandomizer以及一些自定义随机器,在随机的桌面背景上生成随机电路。
为了使合成数据多样化,应该使用各种随机器。Unity Perception自带了一些内置的随机器,并且可以实施自定义随机器。最终数据集具有随机照明、随机相机角度、随机桌面放置、随机桌面纹理和随机电路等功能。通过Unity的内置随机器,可以轻松实现放置、旋转和纹理随机化。要获得随机照明,遵循了Unity的自定义随机器教程。它指导构建照明随机器和需要放置在Unity中的GameObject上的标签,以便Perception知道要随机化哪个GameObject的属性。照明随机器与此类似,但改变的是光线指向的方向,而不是颜色。
对于CircuitRandomizer,它使用以下算法搜索随机电路。一旦找到,它将以包含放置对象所需的所有信息的格式返回。即每个导线/电阻的x位置、y位置、长度和方向。然后它使用这些信息来放置导线。这种关注点分离有助于保持代码的整洁。
protected override void OnIterationStart() {
List<int[]> circuit = findCircuit();
placeCircuit(circuit);
}
对于随机电路,需要正确连接的电路。认为在面包板上进行随机行走会很酷。会从负轨开始,然后随机选择方向,继续放置导线/电阻,直到到达另一边的正轨。实现的算法类似于二维随机行走。图5和图6之间有一些差异。图5每步前进1个单位距离,并从四个方向中随机选择一个方向。允许重叠,并且经常发生。图6从底部负轨开始,并且每步前进一个随机距离(有长度从2到10的导线),并且只向右、左或上移动。另外,如果发生重叠,它会重试。
算法的另一个区别是,需要确保电路保持在面包板上。因此,在每一步,都会检查该步骤是否会超出界限,如果会,则尝试不同的步长和方向。为了确保它保持连接,从与上一步结束时相同的垂直轨(在随机孔中)开始下一步。最后,如果最后一步在上半部分结束,并且随机方向想要向上移动,它会选择正确的导线长度,以完美地终止在顶部正轨。
最终数据集大约有250张真实的电阻、导线和面包板图像。它有500张完全标注的合成生成的图像,这些图像是在随机桌面背景上,具有随机照明和随机相机角度的随机电路。考虑到合成数据都是计算机生成的,训练结果非常好。
合成数据提供了一种廉价且快速的方式来获得大量完美标注的图像数据集。它帮助避免了复杂地标注小型电路组件。该项目的一些可能的下一步包括:识别更多的电路组件,将模型集成到移动应用中,以及检测电阻的值。