3

我正在研究 OCR,现在我正在努力将每个单独的字符与其他字符分开。例如,如果我有一张图片显示以下内容:

12345678.90

我想检测每个数字在图像中的开始位置和结束位置的 x,y 坐标,以便我可以确定要处理的数字数量,然后解析出每个单独的数字/字符,并进行处理。

我设计了一个简单的算法来做这件事,我想要一些关于如何改进它的意见/评论。

(在这个应用程序中,我只需要处理数字,但如果这个算法也能解析出字母,那就更好了)。

  • 1)我会在图像底部以直线读取图像中的像素。例如,如果图像是 30x30,那么我将从 0,30 开始读取到 30,30。

  • 2)我会比较像素的颜色。已经确定了背景和前景颜色,我将比较每个像素的颜色,看看它是在背景中还是在前景中。

  • 3)如果它的背景,它将被忽略。如果我在前景中遇到任何像素,这将表明一个数字的开始。在这种情况下,我会记下位置,然后开始向上读取像素。例如,如果在 5,30 我检测到前景色,我将开始读取 5,29、5,28 等。

  • 4)我会向上(y轴)读取像素,直到遇到背景颜色的像素。这应该给我角色的高度。(我知道对于一些像 5 这样的字符会更复杂,让我们暂时忽略它们)。所以我会确定,例如,角色从 5,20 垂直变为 5,30。

  • 5) 然后我会回到 x 轴 (5,30),在那里我检测到角色的水平起点。我会继续横向阅读以确定字符的宽度,例如 6,30、7,30 等。

  • 6)这是棘手的步骤。我猜,在以下每个字符之间:

    12345678.90

背景颜色有一个像素左右的间隙。而且它可能对我们不可见,但它就在那里,程序会在水平逐个像素地读取颜色时找到它。这将告诉它角色水平结束的位置。因此,例如,它可能会在 15、30 处检测到背景颜色像素。

  • 7)这就是算法,它应该给出x,y每个字母开始和下一个字母开始的坐标。在上面的示例中,字符将从 5,20 运行到 15,30,并且是 10x10。

这个算法可以改进吗,和/或我对第 6 步的假设是否正确?

4

3 回答 3

2

我知道的一种常用的数字分割方法是滑动窗口。基本思想是在数字图像上滑动一些大小的窗口。

滑动窗口的每次移动都会产生一个图像(您只查看窗口覆盖的像素)。滑动窗口会变窄。现在可以训练分类器,它将滑动窗口映射到 1 或 0,其中 1 表示滑动窗口以 2 位分割为中心,0 表示相反。

您需要一些训练数据来训练分类器。或者你可以尝试使用无监督学习。

编辑:这个视频很有用:https ://www.youtube.com/watch?v=y6ga5DeVgSY

于 2013-09-15T21:31:38.657 回答
1

免责声明:我以前从未编写过任何类似 OCR 的软件。

对我来说,您的算法似乎有点不对劲,原因如下:

  • 1 不是从底部的第一个像素开始的,因为在 1 的顶部仍然有指向左侧的小笔划。
  • 2 将只有几个像素高,因为您要一直向上直到找到背景像素。
  • 由于与上述相同的参数,3 将导致只有 1 像素乘 1 像素。
  • ETC...

我会尝试使用递归算法,尽可能地遵循前景色像素而不进入背景像素。当使用带有大字符的大图像时,这可能会导致堆栈溢出,因此最好在几个 for 循环中完成这个技巧,而不是使用递归函数。

如果您正在逐个像素地发现一个字符,则可以使用该过程创建有关您的字符外观的矢量信息。我认为这将是识别角色的一个很酷的起点。

于 2013-09-15T21:24:26.583 回答
1

我没有尝试编写 OCR 软件,但我们确实使用它,而且它(或可能)变得非常复杂。

您的图像来自哪里并不完全清楚。如果它是扫描图像,那么有几个复杂性。尤其是关于您的计划,即使数字之间存在间隙,它也可能不是垂直的(扫描的页面不太可能完全笔直)。其他因素包括“斑点”——由图像或扫描仪上的污垢等引起的随机点。如果您正在处理这种图像,您几乎肯定需要研究图像处理技术,这些技术将许多不同的数学运算应用于整个像素阵列,以执行诸如去歪斜(拉直图像)、去斑(消除随机点)之类的事情); 边缘增强(加强从浅到深的变化以增强线条)。

从您对“背景”和“前景”颜色的使用来看,您可能正在尝试“OCR”屏幕上的图像?如果是这样(某种“屏幕抓取”过程),并且您知道(或可以接受训练)正在解释的特定字符形状,那么滑动窗口的变体可能会有所帮助:您滑动已知图像' 5' 以不同的偏移量围绕图像:如果 '5' 的所有像素都与图像中的“前景”像素匹配,那么你知道你找到了一个 '5'。重复其他数字。如上所述,这是我们正在谈论的“虚拟”窗口。

于 2014-04-22T10:46:25.413 回答