请注意,我真的在寻找我的问题的答案。我不正在寻找一些源代码或一些学术论文的链接:我已经使用了源代码,我已经阅读了论文,但仍然没有找到最后一部分问题...
我正在进行一些快速屏幕字体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”区分开来的事情并不是真正的问题)
答案 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倍,以便更好地查看像素。
我手动计算(希望正确)标准化的链码:
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
。
此方法不是缩放不变的。我认为有两种方法可以解决这个问题:
我不太确定距离函数对于所有字母数字字母的集合是否足够好,但我希望如此。为了最大限度地减少识别字母时的错误,您可以在分类步骤中包含其他功能(不仅仅是链代码)。再次,你需要一个距离测量 - 这次是特征向量。
答案 1 :(得分:3)
由于你的问题不够具体(无论你想要基于链码的完整算法还是只需要一些概率分类),我都会告诉你我对这个问题的了解。
使用链码,您可以计算符号的某些属性,例如形式为344445,244445,2555556,344446(任意数量为4s)的旋转的数量,即字母上的“尖峰”。假设链码中有3个部分看起来像这样。所以,这几乎肯定是“W”!但这是一个很好的例子。您可以计算不同类型旋转的数量,并将其与每个字母(您手动执行)的先前保存的值进行比较。 这是一个非常好的分类器,但当然还不够。它不可能区分“D”和“O”,“V”和“U”。很大程度上取决于你的想象力。
首先应该创建一个带参考的某些字母图像的测试用例,然后在更改和发明新标准之间检查算法。
希望这至少可以部分回答你的问题。
<强>更新强>:
一个好主意刚进入我的脑海:)
您可以计算链中单调序列的数量,例如,对于链000111222233334443333222444455544443333(一个快速的哑巴示例,并不真正对应任何字母)我们有
00011122223333444 3333222444455544443333,
00011122223333444 3333222 444455544443333,
000111222233334443333222 4444555 44443333,
0001112222333344433332224444555 44443333 ,
即。四个单调子序列。
这应该是一个很好的概括,只计算真实字母的这些变化的数量,并与从检测到的链中获得的变化进行比较,这是一个很好的尝试。
一些问题和想法:
答案 2 :(得分:0)
您可以将链代码转换为更简单的模型,该模型传达拓扑,然后运行机器学习代码(可能在Prolog中编写代码)。
但我不赞成。人们多年来一直在尝试这种做法,但我们仍然没有取得好成绩。
为什么不使用基于相关性的强大技术,而不是在基于非线性/阈值的方法上浪费时间?最简单的方法是使用模板进行卷积。
但是我会在字母上开发 Gabor小波并将系数分类到向量空间。使用一些示例训练支持向量机,然后将其用作分类器。
这就是我们的大脑如何做到这一点,我确信它可以在计算机中使用。
一些随机聊天聊天(忽略):
我不会使用神经元网络,因为我不理解它们,因此不喜欢它们。 但是,我总是对Geoff Hintons小组http://www.youtube.com/watch?v=VdIURAu1-aU的工作印象深刻。
不知何故,他在可以向后传播信息的网络上工作(深度学习)。 有一个关于他的谈话,他让训练有素的数字识别网络梦想。这意味着他将其中一个输出神经元设置为“2”,并且网络将生成它认为在输入神经元上的两个事物的图片。
我发现这很酷。
答案 3 :(得分:0)
上个月,我正在处理同样的问题。现在,我已经通过vetex链码解决了这个问题。
vetex链码是二进制链码。然后,我把它切成5份。显然,数字0-9在不同的部分有自己的特征。