以编程方式识别手写形状:找到矩形的关键点
我的一个不切实际的目标是使用白板上的草图作为定义程序的方法 。 我的意思是您可以执行的正式程序。 当然,通过草图,您可以使用高级领域特定语言定义程序,例如描述状态机或实体关系图。
为此,我想开始识别矩形。 然后,我将继续识别其他形状,连接线并识别图中存在的文本。 现在,让我们专注于识别矩形。
我的一般方法如下:
- 认识有意义的路线
- 识别那些线中的关键点
- 使用AI对这些关键点进行分类
- 通过组合分类的关键点来找到形状
好。 这将不是我在一个周末内完成的工作。
输入图像
我们将使用3张图像:我在不同的光照条件下在白板上绘制了2张图像。 第三个是在Internet上找到的。 其特殊之处在于,草图是在方格纸上绘制的(即,在纸上有网格)。
让我们看看如何处理这些图像。 我们将使用Java和BoofCV图像处理库。
灰阶
首先,我们将图像转换为灰度。 在这里我们遇到了在人造光下拍摄的图像的问题:
我们要删除右下角的那个巨大的灰色斑点。 为此,我们将使用导数。
衍生品
我们对图像进行模糊处理,以减少噪声的影响并计算导数。 这是一种捕获垂直或水平出现的颜色急剧变化的方法。
对于在自然光下拍摄的图像,我们将得到如下所示的图像:
但是,对于在人造光下拍摄的图像,我们会看到噪声:
在这一点上,我们获取图像的每个点,并查看图像周围是否有大量具有高导数的点(水平或垂直)。 我们保持满足条件的点,并将所有其他点设置为白色。 我们做了几次。
结果如下:
等高线
我们进行了一些额外的过滤,然后调用一个函数来查找图像内部的轮廓。 我们将外部轮廓绘制为红色,将内部轮廓绘制为蓝色。
然后我们删除短轮廓
关键点
我们得到的轮廓被绘制为非常短的线段列表。 让我们用蓝色绘制分段的极限。
是的,它们很短:您只会看到一系列连续的极端,彼此之间非常接近。 我们希望获得更少的细分市场,更长的时间。
为此,我们基本上使用两种策略:
- 我们只是合并非常接近的连续极限
- 我们采用三个连续点的序列:A,B,C。如果B非常靠近A和C之间的线,我们只需移除B
我们对这两种策略都应用了两次,并获得了更简单的轮廓。 这是最终结果。
接下来是什么
现在我们有合理数量的相关点。 我现在想通过机器学习技术对它们进行分类。 例如,我想将单个点识别为矩形的左上角或箭头的点部分。 然后,我将结合这些公认的点来获得整个形状(我的矩形!)。
现在,我已经在生成图像进行分类,并且正在考虑将哪些功能用于机器学习。 我有一些想法,但我们将在下一篇文章中看到它们。
训练图像如下所示: