10

我用 Python 编写了一个程序,它会自动读取像这样的成绩单 纠偏后的片材

目前我正在使用以下基本策略:

  • 使用 ImageMagick 歪斜图像
  • 使用 PIL 读入 Python,将图像转换为黑白
  • 计算计算行和列中像素的总和
  • 在这些总和中找到峰值
  • 检查这些峰所暗示的交叉点是否填充。

运行程序的结果如下图所示: 处理后的图像

您可以在左上方显示的图像下方和右侧看到峰值图。左上图中的线条是列的位置,红点表示已识别的分数。右下角的直方图显示了每个圆圈的填充水平和分类线。

这种方法的问题在于它需要仔细调整,并且对扫描设置的差异很敏感。是否有一种更稳健的方式来识别网格,这将需要更少的先验信息(目前我正在使用关于有多少点的知识)并且对于人们在图纸上绘制其他形状更稳健?我相信使用 2D Fourier Transform 可能是可能的,但我不确定如何。

我正在使用环保署,所以我有很多图书馆可供我使用。

4

2 回答 2

2

正确的方法是对图像使用连通分量分析,将其分割成“对象”。然后,您可以使用更高级别的算法(例如组件质心上的霍夫变换)来检测网格,并通过查看每个单元格包含的活动像素数来确定它是否打开/关闭。

于 2013-05-16T06:00:45.697 回答
2

首先,我发现您的初始方法非常合理,我可能会尝试相同的方法(我特别欣赏行/列投影,然后是直方图,这是一种被低估的方法,在实际应用中通常非常有效)。

但是,由于您想要使用更强大的处理管道,因此这里有一个可能完全自动化的建议(同时也通过 ImageMagick 消除偏斜):

  1. 特征提取:通过广义霍夫变换提取圆。正如其他答案中所建议的,您可以为此使用 OpenCV 的 Python 包装器。检测器可能会漏掉一些圆圈,但这并不重要。
  2. 使用圆心应用稳健的对齐检测器。您可以使用此处描述的 Desloneux 无参数检测器。不要被数学吓到,这个过程很容易实现(你可以在网上找到示例实现)。
  3. 通过选择方向来消除对角线。
  4. 找到线的交点以获得点。您可以通过为这些交叉点假设理想的固定位置来使用这些坐标进行偏斜校正。

这个管道可能有点 CPU 密集型(尤其是第 2 步,它将继续进行某种贪婪搜索),但它应该非常健壮和自动。

于 2013-05-16T07:12:50.080 回答