12

这是我正在做的事情,我想从 StackOverflow 上的聪明人那里得到意见。

我正在尝试的是一种基于组合同一文本页面的各种错误版本来修复文本的功能。基本上,这可用于将不同的 OCR 结果组合成一个,其准确性比单独的任何一个都高。

我从一本包含 600,000 个英语单词的字典开始,这几乎是所有内容,包括法律和医学术语以及常用名称。我已经有了这个。

然后我有 4 个版本的文本示例。

像这样的东西:

$text[0] = 'Fir5t text sample is thisline';
$text[1] = 'Fir5t text Smplee is this line.';
$text[2] = 'First te*t sample i this l1ne.';
$text[3] = 'F i r st text s ample is this line.';

我试图将上述内容结合起来以获得如下所示的输出:

$text = 'First text sample is this line.';

不要告诉我这是不可能的,因为它肯定不是,只是非常困难。

我非常感谢任何人对此的任何想法。

谢谢!

我目前的想法:

仅仅根据字典检查单词是行不通的,因为有些空格在错误的位置,有时单词不会出现在字典中。

主要关注的是修复损坏的间距,一旦修复,则可以选择最常出现的字典单词(如果存在),或者选择最常出现的非字典单词。

4

5 回答 5

8

您是否尝试过使用最长公共子序列算法?这些在源代码管理应用程序和一些文本编辑器中使用的“差异”文本比较工具中很常见。diff 算法有助于识别两个文本样本中已更改和未更改的字符。 http://en.wikipedia.org/wiki/Diff

几年前,我开发了一个与您类似的 OCR 应用程序。我没有将多个 OCR 引擎应用于一张图像,而是使用一个 OCR 引擎来分析同一图像的多个版本。每个处理后的图像都是对原始图像应用不同去噪技术的结果:一种技术在低对比度下效果更好,另一种技术在字符形成不良时效果更好。比较每个图像上的 OCR 结果的“投票”方案提高了任意文本字符串的读取率,例如“BQCM10032”。OCR 的学术文献中描述了其他投票方案。

有时您可能需要匹配一个没有任何 OCR 结果组合会产生所有字母的单词。例如,可能缺少中间字母,如“w rd”或“c tch”(可能是“word”和“catch”)。在这种情况下,它可以帮助您使用三个键中的任何一个来访问您的字典:首字母、中间字母和尾字母(或字母组合)。每个键都与按语言中出现频率排序的单词列表相关联。(我使用这种多键查找来提高填字游戏生成应用程序的速度;可能有更好的方法,但这个很容易实现。)

为了节省内存,您可以只对语言中的前几千个常用词应用多键方法,然后对不太常用的词只使用一种查找技术。

有几个在线词频列表。 http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists

如果你想变得花哨,你也可以依靠文本中的先前出现频率。例如,如果“Byrd”多次出现,那么如果 OCR 引擎报告“bird”或“bard”的置信度得分较低,则可能是更好的选择。仅当在同一页面上出现统计上不太可能的医学术语时,您才可以将医学词典加载到内存中——否则将医学术语从您的工作词典中删除,或者至少为它们分配合理的可能性。“假肢”是一个常用词;“前列腺炎”就更少了。

如果您有图像处理技术(例如去噪和形态学运算)的经验,您还可以尝试在将图像传递给 OCR 引擎之前对其进行预处理。在您的软件识别出 OCR 引擎表现不佳的单词或区域后,图像处理也可以应用于选择区域。

某些字母/字母和字母/数字替换很常见。数字 0(零)可能与字母 O、C 代表 O、8 代表 B、E 代表 F、P 代表 R,等等。如果发现一个词的置信度较低,或者如果有两个常见词可以匹配一个未完全阅读的词,那么特别的形状匹配规则可能会有所帮助。例如,“bcth”可以匹配“both”或“bath”,但对于许多字体(和上下文),“both”更可能匹配,因为“o”在形状上更类似于“c”。在长长的单词串中,例如小说或杂志文章中的一段,“bath”比“b8th”更合适。

最后,您可能会编写一个插件或脚本将结果传递给一个拼写检查引擎,该引擎检查名词-动词一致性和其他语法检查。这可能会捕获一些额外的错误。也许您可以尝试 VBA for Word 或任何其他流行的脚本/应用程序组合。

于 2011-12-18T04:49:44.787 回答
1

您可以尝试使用 google n-grams 来实现这一点。

于 2011-12-15T10:42:55.590 回答
1

自己处理这样的复杂算法可能比使用第三方工具需要更长的时间并且更容易出错——除非你真的需要自己编程,你可以查看Yahoo Spelling Suggestion API。我相信,他们每天允许每个 IP 5.000 个请求。

其他人可能会提供类似的东西(我认为也有一个 bing API)。

更新:对不起,我刚刚读到他们已经在 2011 年 4 月停止了这项服务。他们声称现在提供类似的服务,称为“拼写建议 YQL 表”。

于 2011-12-15T10:31:44.967 回答
1

这确实是一个相当复杂的问题。

当我想知道如何拼写一个单词时,直接的方法就是打开字典。但是,如果我试图正确拼写一个复杂的小句子怎么办?我个人的一个技巧,大部分时间都有效,就是打电话给谷歌。我将我的句子放在谷歌的引号之间并计算结果。这是一个例子:在谷歌上输入“你很聪明”会得到 13'600k 页面。输入“你很聪明”会得到 20'000k 页。那么,正确的拼写很可能是“你很聪明”。而且......确实是;)

基于这个概念,我猜你有一些样本,在大多数情况下,拼写错误(好吧,如果你是为青少年游戏网站开发的,可能不是......)。您可以尝试将样本分成子片段,而不是单词,并按频率匹配它们吗?最常见的部分是最有可能拼写正确的。在此之前,您已经可以对 600,000 个术语进行字典拼写检查,以增加已经纠正小的拼写错误的机会。这应该会增加正确子片段的频率。

将句子分成几块并找到合适的“块大小”也很棘手。

我也有点担心:你如何提取样本并将它们匹配在一起以知道正确拼写的句子是相同的(或非常接近?)。你的问题似乎假设你有这个,这对我来说似乎也很复杂。

好吧,前面的只是基于我个人和人类经验的一般提示。Donno 如果这可以帮助。这显然不是一个真正的答案,也不意味着是一个。

于 2011-12-15T10:39:36.657 回答
1

如果您只需要通过比较其他字符串来获得正确的字符串。那么这样的事情可能会有所帮助。

它还没有完成,但已经给出了一些结果。

$text[0] = 'Fir5t text sample is thisline';
$text[1] = 'Fir5t text Smplee is this line.';
$text[2] = 'First te*t sample i this l1ne.';
$text[3] = 'F i r st text s ample is this line.';

function getRight($arr){
    $_final='';
    $count=count($arr);

    // Remove multi spaces AND get string lengths
    for($i=0;$i<$count;$i++){
        $arr[$i]=preg_replace('/\s\s+/', ' ',$arr[$i]);
        $len[$i]=strlen($arr[$i]);
    }

    // Max length
    $_max=max($len);

    for($i=0;$i<$_max;$i++){
        $_el=array();
        for($j=0;$j<$count;$j++){
            // Cheking letter counts
            $_letter=$arr[$j][$i];
            if(isset($_el[$_letter]))$_el[$_letter]++;
            else$_el[$_letter]=1;
        }
        //Most probably count
        list($mostProbably) = array_keys($_el, max($_el));

        $_final.=$mostProbably;

        // If probbaly example is not space
        if($_el!=' '){
            // THERE NEED TO BE CODE FOR REMOVING SPACE FROM LINES WHERE $text[$i] is space
        }
    }

    return $_final;
}


echo getRight($text);
于 2011-12-15T10:46:16.657 回答