了解OCR的Freeman链码

时间:2011-07-16 15:58:28

标签: algorithm ocr

请注意,我真的在寻找我的问题的答案。我正在寻找一些源代码或一些学术论文的链接:我已经使用了源代码,我已经阅读了论文,但仍然没有找到最后一部分问题...

我正在进行一些快速屏幕字体OCR,我正在取得很好的进展。

我已经找到了基线,将角色分开,将每个角色转换为黑色和黑色。白色然后勾勒出每个角色的轮廓,以便将Freeman链码应用于它。

基本上它是一个8连接的链码,如下所示:

  3  2  1
   \ | /
  4-- --0
   / | \
  5  6  7

所以,如果我有一个'a',经过我所有的转换(包括转换为黑白),我最终会得到这样的结果:

11110
00001
01111
10001
10001
01110

然后它的外部计数可能看起来像这样(我可能在这里犯了一个错误,这是ASCII艺术轮廓而我的'算法'可能会使轮廓错误但这不是我的问题):

 XXXX
X1111X
 XXXX1X
X01111X
X10001X
X10001X
 X111X
  XXX

在Xs之后,我得到了链代码,它将是:

0011222334445656677

请注意,这是规范化的链代码,但您始终可以将链式代码规范化,如下所示:您只需保留最小的整数。

(顺便说一下,有一个超级高效的实现来找到链代码,你只需要取一个'X'的8个相邻像素然后查看256查找表,如果你有0,1, 2,3,4,5,6或7)

然而,现在我的问题是:从那个0011222334445656677链码开始,我怎么发现我有'a'?

因为,例如,如果我的'a'看起来像这样:

11110
00001
01111
10001
10001
01111  <-- This pixel is now full

然后我的链码现在是:0002222334445656677

然而这也是'a'。

我知道这些链码的重点是能够适应这些微小的变化,但我无法弄清楚我应该如何找到哪个字符对应一个链码。

我已经走得那么远了,现在我被卡住了......

(顺便说一下,我不需要100%的效率,将“0”与“O”或“o”区分开来的事情并不是真正的问题)

4 个答案:

答案 0 :(得分:18)

您需要的是一个测量链码之间距离的函数d。之后找到给定链码的字母很简单:

输入:

  • 标准化链码S表示可能的字母组(通常为A-Z,a-z,0-9,...的cain代码)
  • 需要检测到并且可能稍微变形的字母的链代码x(链代码与集合S中的任何链代码都不匹配)

算法将遍历可能的链码集并计算每个元素的距离d(x,si)。距离最小的字母将是算法的输出(标识的字母)。

我建议遵循距离函数: 对于两个链代码,将每个方向的长度差异相加:d(x,si) = |x0-si0| + |x1-si1| + .. + |x7-si7|x0是链代码x中的0的数量,si0是链代码si中的0的数量等。

一个例子可以更好地解释我在想什么。在下图中有字母8,B和D,第四个字母是稍微变形的8,需要识别。字母用Arial写入,字体大小为8.图像中的第二行放大10倍,以便更好地查看像素。

enter image description here

我手动计算(希望正确)标准化的链码:

8:  0011223123344556756677
B:  0000011222223344444666666666
D:  00001112223334444666666666
8': 000011222223344556756666 (deformed 8)

长度差异(绝对值)是:


direction | length         | difference to 8'
          | 8 | B | D |  8'|   8 |  B |  D |
----------+---+---+---+----+-----+----+-----
        0 | 2 | 5 | 4 |  4 |   2 |  1 |  0 |
        1 | 3 | 2 | 3 |  2 |   1 |  0 |  1 |
        2 | 3 | 5 | 3 |  5 |   2 |  0 |  2 |
        3 | 3 | 2 | 3 |  2 |   1 |  0 |  1 |
        4 | 2 | 5 | 4 |  2 |   0 |  3 |  2 |
        5 | 3 | 0 | 0 |  3 |   0 |  3 |  3 |
        6 | 3 | 9 | 9 |  5 |   2 |  4 |  4 |
        7 | 3 | 0 | 0 |  1 |   2 |  1 |  1 |
----------+---+---+---+----+-----+----+-----
                        sum   10 | 12 | 14 |

8'8的链代码的距离最小,因此算法会识别字母8。字母B的距离并不大,但这是因为变形的8看起来几乎像B

此方法不是缩放不变的。我认为有两种方法可以解决这个问题:

  • 对于不同的字体大小,具有不同的规范化链代码集
  • 大尺寸(例如35x46像素)的一组标准化链码,并将输入字母(需要识别)缩放到更大的尺寸。

我不太确定距离函数对于所有字母数字字母的集合是否足够好,但我希望如此。为了最大限度地减少识别字母时的错误,您可以在分类步骤中包含其他功能(不仅仅是链代码)。再次,你需要一个距离测量 - 这次是特征向量。

答案 1 :(得分:3)

由于你的问题不够具体(无论你想要基于链码的完整算法还是只需要一些概率分类),我都会告诉你我对这个问题的了解。

使用链码,您可以计算符号的某些属性,例如形式为344445,244445,2555556,344446(任意数量为4s)的旋转的数量,即字母上的“尖峰”。假设链码中有3个部分看起来像这样。所以,这几乎肯定是“W”!但这是一个很好的例子。您可以计算不同类型旋转的数量,并将其与每个字母(您手动执行)的先前保存的值进行比较。 这是一个非常好的分类器,但当然还不够。它不可能区分“D”和“O”,“V”和“U”。很大程度上取决于你的想象力。

首先应该创建一个带参考的某些字母图像的测试用例,然后在更改和发明新标准之间检查算法。

希望这至少可以部分回答你的问题。

<强>更新: 一个好主意刚进入我的脑海:) 您可以计算链中单调序列的数量,例如,对于链000111222233334443333222444455544443333(一个快速的哑巴示例,并不真正对应任何字母)我们有 00011122223333444 3333222444455544443333,
00011122223333444 3333222 444455544443333,
000111222233334443333222 4444555 44443333,
0001112222333344433332224444555 44443333

即。四个单调子序列。

这应该是一个很好的概括,只计算真实字母的这些变化的数量,并与从检测到的链中获得的变化进行比较,这是一个很好的尝试。

一些问题和想法:

  1. 链在某种程度上是循环的,所以你应该处理检测链末端的单调(以避免一个一个错误),
  2. 应该考虑一些工件,例如,如果你知道字母足够大(例如,高度为20像素),你会想要忽略短于3个项目的单调中断,例如:)

答案 2 :(得分:0)

您可以将链代码转换为更简单的模型,该模型传达拓扑,然后运行机器学习代码(可能在Prolog中编写代码)。

但我不赞成。人们多年来一直在尝试这种做法,但我们仍然没有取得好成绩。

为什么不使用基于相关性的强大技术,而不是在基于非线性/阈值的方法上浪费时间?最简单的方法是使用模板进行卷积。

但是我会在字母上开发 Gabor小波并将系数分类到向量空间。使用一些示例训练支持向量机,然后将其用作分类器。

这就是我们的大脑如何做到这一点,我确信它可以在计算机中使用。

一些随机聊天聊天(忽略):

我不会使用神经元网络,因为我不理解它们,因此不喜欢它们。 但是,我总是对Geoff Hintons小组http://www.youtube.com/watch?v=VdIURAu1-aU的工作印象深刻。

不知何故,他在可以向后传播信息的网络上工作(深度学习)。 有一个关于他的谈话,他让训练有素的数字识别网络梦想。这意味着他将其中一个输出神经元设置为“2”,并且网络将生成它认为在输入神经元上的两个事物的图片。

我发现这很酷。

答案 3 :(得分:0)

上个月,我正在处理同样的问题。现在,我已经通过vetex链码解决了这个问题。

vetex链码是二进制链码。然后,我把它切成5份。显然,数字0-9在不同的部分有自己的特征。