1

我一直在开发一个程序,该程序将读取 OCR 输出,找到页码,然后将它们还给我。每当我的函数找到一个数字时,它就会开始一个序列,然后它会在下一页上查找比前一个大 1 的数字。它还可以添加空格来推断缺失的数字。

在任何给定的书中,我的函数将识别 1-100 个潜在序列。它识别的许多序列都是垃圾……完全没用。然而,其他的通常是主要序列的子集,可以拼接在一起形成更全面的序列。这是我的问题:我如何将它们缝合在一起?我的输出现在看起来像这样:

 Index: 185 PNUM: 158   
 Index: 186 PNUM: 159   
 Index: 187 PNUM: 160   
 Index: 188 PNUM: 161   
 Index: 189 PNUM: 162   
 Index: -1 PNUM: blank   
 Index: -1 PNUM: blank   
 -------------------------------------------------
 Index: 163 PNUM: 134   
 Index: 164 PNUM: 135   
 Index: -1 PNUM: blank   
-------------------------------------------------
 Index: 191 PNUM: 166   
 Index: 192 PNUM: 167   
 Index: 193 PNUM: 168   
 Index: 194 PNUM: 169   

索引是书籍封面的页数,包括所有那些传统上未编号的版权、奉献、目录页数。PNUM 是我的算法检测到的页码。在这里我们可以看到三个不同的序列,它们的顶部和底部应该缝合在一起。您会注意到顶部序列的索引和 pnum 之间的偏移量是 27,而底部序列的偏移量是 25。偏移量之间存在差异的最常见原因是缺少页面,或者页面扫描了两次。

有人建议我使用 Viterbi 最佳路径算法将这些序列拼接在一起,但这对我来说似乎有点矫枉过正,因为我真的只需要将我的序列拼接在一起,而不是确认它们的准确性。我真的不知道该去哪里,我非常感谢任何帮助。谢谢!

4

1 回答 1

0

维特比

是的,维特比会工作,稍微有点矫枉过正,但稍后会给你很大的灵活性来弥补 OCR 中的问题、丢失页面、重复等......

如果您采用维基百科伪代码,您的问题可以重新表述为

//this is the actual hidden variable you're trying to guess
states = ('i', 'ii', 'iii', 'iv', ...., '1','2','3' ....)

//what OCR will give you, a 98% accurate view of state
//blank is for when there is no page number
//other is for an OCR result you didn't anticipate, such as 'f413dsaf'
possible_observations = (blank,other, 'i','ii','iii','iv',...,'1','2','3'...)

//the probability distribution of states for the first page
//must sum to 1.0
start_probability = {'i': 0.2, '1':0.5, all the rest: (1-0.7)/numOtherStates}

//the probability that the state '2' is found after '1'
//let's put a 0.05 percent chance of duplicate
//and put a very small probability of getting somewhere random
transition_probability = {
'i' : {'ii':0.8,'1':0.1,'i':0.05,allOthers: 0.05/numOtherStates},
'1' : {'2': 0.9, '1': 0.05, allOthers: 0.05/numOtherStates}
//etc
}

//that's the probability of what you OCR will see given the true state
//for the true page '1', there's 95% percent chance the OCR will see '1', 1% it will see    
//'i', 3% it will see a blank, and 0.01%/otherObservation that it will OCR something else
//you can use some string distance for that one (Levenshtein etc...)
emission_probability = {
'1' : {'1': 0.95, 'i': 0.01, blank: 0.03, otherObservations: (0.01)/numObservations},
'2' : {'2': 0.95, 'z': 0.01, blank: 0.03, otherObservations: (0.01)/numObservations},
}

observations = for i = 1 to maxINDEX {PNUM[INDEX]}

其他可能性:使用 levenshtein 距离

再次将所有页码依次放入数组 {PNUM[INDEX=0], PNUM[INDEX=1], ...} 中,并尝试将其与 1、2、3、... MAX(PNUM) 匹配。在计算距离时,levenshtein 算法将插入更改(删除、插入、页面更改)。如果您对其进行编码以显示这些更改,那么您也应该有一些不错的东西。

于 2014-08-26T03:07:11.747 回答