【问题标题】:Robust detection of grid pattern in an image图像中网格图案的鲁棒检测
【发布时间】:2013-05-16 05:56:13
【问题描述】:

我用 Python 编写了一个程序,它可以自动读取像这样的成绩单

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

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

运行程序的结果如下图所示:

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

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

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

【问题讨论】:

  • 您可以尝试使用霍夫变换进行圆圈搜索。或者甚至只是将扫描图像与单个圆圈图像进行互相关。峰值会显示所有圆的坐标,微调(中值甚至最小二乘法)会给你精细的网格。

标签: python image-processing


【解决方案1】:

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

【讨论】:

  • +1。另外,我建议 OP 看看opencv.org——它非常适合 Python 中的图像处理
  • 您能否详细说明使用霍夫变换来查找网格形状?我熟悉使用它来查找线条,但我确信可以利用网格是一种很好的重复模式这一事实。
  • 如果您将组件质心的位置视为您输入到霍夫变换中的数据点(而不是单个像素),您将获得对单元格线的非常快速的“低分辨率”分析安排好。这也可以消除预先进行纠偏的需要。另一种选择是使用 Ransac 来确定网格的排列。一旦从像素级别转移到组件级别,事情就会变得更加直观,您基本上可以轻松提出强大的解决方案。
  • 你的建议是合理的,但称其为“正确的方式”有点夸张。有多种同样合理的方法可以解决这个问题。
【解决方案2】:

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

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

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

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

【讨论】:

  • 链接已失效。
猜你喜欢
  • 1970-01-01
  • 2022-06-12
  • 1970-01-01
  • 2016-03-04
  • 2015-04-27
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多