如何有效地检测和删除扫描图像/文档中的引导线?

时间:2010-06-23 05:05:53

标签: java c++ math image-processing image-segmentation

对于我的项目,我正在为扫描文档编写图像预处理库。截至目前,我仍然坚持使用线删除功能。

问题描述: 扫描样本表格:

Name*  : ______________________________
Age* : ______________________________

Email-ID: |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|

注意:的 以下是进一步的条件:

  • 扫描的文档可能包含更多垂直和水平引导线。
  • 线条的粗细可能超过1px
  • 文档本身打印不正确,可能会出现墨水膨胀或厚度不均匀的噪音
  • 文档可能带有彩色背景或线条

现在我要做的是检测这些行并删除它们。在这样做的同时,手写内容不应该丢失。

解决方案是这样的: 当前的解决方案是用Java实现的。

通过结合使用canny / sobel边缘检测器和阈值滤波器(使图像呈双色调)来检测这些线条。从前一个动作我得到一个黑白像素数组。遍历数组并检查该像素的光度是否低于指定的bin值。如果我找到30(像素的最小行长度)这样的像素,我删除它们。我对垂直线重复相同,但考虑到由于水平线移除会有切割的事实。

虽然解决方案似乎有效。但是有一些问题,比如,

  • 删除重叠字符
  • 如果图像中的字符间距不正确,那么它也是如此 被视为一条线。
  • 边缘检测的输出图像为黑白色。
  • 有点慢。对于2480 * 3508的图像,通常需要大约40秒。

请指导如何正确有效地完成工作。如果有一个开源库,请直接。

由于

1 个答案:

答案 0 :(得分:1)

首先,我想提一下,我对图像处理一般都不了解,特别是关于OCR。

仍然,我想到了一个非常简单的启发式方法:

  1. 将图像中的像素分隔为连接的组件。
  2. 对于每个连接的组件,使用以下一个或多个启发式方法确定它是否为一行:
    1. 平均字母长度是否更长?
    2. 它是否出现在其他字母附近? (删除墨水膨胀或文物)。
    3. 它的X渐变和Y渐变是否足够大?这可以确保此连接的组件不仅包含水平线。
  3. 我能看到的唯一问题是,如果有人在水平线上写字母,就像这样:

       /\     ___
      /  \   /   \
      |__|   |___/
     -|--|---|---|------------------
      |  |    \__/
    

    在这种情况下,该行将保留,但无论如何你必须处理这个案例。

    正如我所提到的,我绝不是图像处理专家,但有时非常简单的技巧。