PHP修复坏文本

时间:2011-12-15 10:14:42

标签: php algorithm text ocr text-manipulation

这是我正在努力的事情,我想在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.';

不要告诉我这是不可能的,因为它当然不是,非常困难。

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

谢谢!

我目前的想法:

只是检查字典中的单词是行不通的,因为有些空格位于错误的地方,偶尔单词也不会出现在字典中。

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

5 个答案:

答案 0 :(得分:8)

您是否尝试使用最长的常见子序列算法?这些常见于源控制应用程序和一些文本编辑器中使用的“diff”文本比较工具中。 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引擎报告具有低置信度得分的“鸟”或“吟游诗人”,则可能是更好的选择。只有在同一页面上出现统计上不太可能出现的医学术语时,您才可以将医学词典加载到内存中 - 否则将医学术语从您的工作词典中删除,或者至少为其分配合理的可能性。 “修复术”是一个常用词; “前列腺炎”不那么。

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

某些字母/字母和字母/数字替换很常见。数字0(零)可以与字母O混淆,C代表O,8代表B,E代表F,P代表R,依此类推。如果找到一个信心不足的单词,或者有两个常用单词可以匹配一个不完整读取的单词,那么ad hoc形状匹配规则可能有所帮助。例如,“bcth”可以匹配“both”或“bath”,但是对于许多字体(和上下文),“both”更可能匹配,因为“o”在形状上更类似于“c”。在诸如小说或杂志文章的段落之类的长串词汇中,“浴”是比“b8th”更好的匹配。

最后,你可能会编写一个插件或脚本来将结果传递给一个拼写检查引擎来检查名词 - 动词协议和其他语法检查。这可能会带来一些额外的错误。也许你可以尝试使用VBA for Word或其他任何脚本/应用程序组合这些天很受欢迎。

答案 1 :(得分:1)

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

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

更新抱歉,我刚看到他们已于2011年4月停止了这项服务。他们声称现在提供类似的服务,名为“Spelling Suggestion YQL table”。

答案 2 :(得分:1)

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

当我想知道如何拼写单词时,直接的方法是打开字典。但是如果它是一个小的复杂句子,我正在尝试正确拼写呢?我个人的伎俩之一就是打电话给谷歌。我将句子放在Google上的引号之间并计算结果。这是一个例子:在Google上输入“你非常聪明”给出13'600k的页面。输入“你非常聪明”可以获得20万页。然后,正确的拼写可能是“你非常聪明”。并且......确实是;)

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

将句子分成片并找到正确的“片段大小”也很棘手。

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

嗯,先前的内容只是基于我个人和人类经验的一般提示。唐诺,如果这可以帮助。这显然不是一个真正的答案,并不一定是一个。

答案 3 :(得分:1)

您可以尝试使用谷歌n-gram来实现这一目标。

答案 4 :(得分: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);