OCR字识别逻辑

时间:2013-07-11 15:56:03

标签: c# ocr tessnet2

下面是一个函数,它使用TessNet2(OCR框架)扫描由TessNet2内置的OCR函数捕获的单词列表。由于我扫描的页面质量不够理想,因此单词的检测并不是100%准确。

所以有时它会将'S'与'5'或'l'混淆为'1'。此外,它没有考虑资本化。所以我必须搜索这两种情况。

它的工作方式是我在纸上寻找彼此接近的某些词。所以第一组单词[I]是“抽象服务有序”。如果页面包含彼此相邻的那些单词,则它将移动到下一组单词[j],然后移动到下一个单词[h]。如果页面包含所有3组单词,则返回true。

这是我想过的最好的方法,但我希望有人可以给我另一种尝试方法。

public Boolean isPageABSTRACTING(List<tessnet2.Word> wordList)
    {

        for (int i = 0; i < wordList.Count; i++) //scan through words
        {
            if ((wordList[i].Text == "Abstracting" || wordList[i].Text == "abstracting" || wordList[i].Text == "abstractmg" || wordList[i].Text == "Abstractmg" && wordList[i].Confidence >= 50) && (wordList[i + 1].Text == "Service" || wordList[i + 1].Text == "service" || wordList[i + 1].Text == "5ervice" && wordList[i + 1].Confidence >= 50) && (wordList[i + 2].Text == "Ordered" || wordList[i + 2].Text == "ordered" && wordList[i + 2].Confidence >= 50)) //find 1st tier check
            {
                for (int j = 0; j < wordList.Count; j++) //scan through words again
                {
                    if ((wordList[j].Text == "Due" || wordList[j].Text == "Oue" && wordList[j].Confidence >= 50) && (wordList[j + 1].Text == "Date" || wordList[j + 1].Text == "Oate" && wordList[j + 1].Confidence >= 50) && (wordList[j + 2].Text == "&" && wordList[j + 2].Confidence >= 50)) //find 2nd tier check
                    {
                        for (int h = 0; h < wordList.Count; h++) //scan through words again
                        {
                            if ((wordList[h].Text == "Additional" || wordList[h].Text == "additional" && wordList[h].Confidence >= 50) && (wordList[h + 1].Text == "comments" || wordList[h + 1].Text == "Comments" && wordList[h + 1].Confidence >= 50) && (wordList[h + 2].Text == "about" || wordList[h + 2].Text == "About" && wordList[h + 2].Confidence >= 50) && (wordList[h + 3].Text == "this" || wordList[h + 3].Text == "This" && wordList[h + 3].Confidence >= 50)) //find 3rd tier check
                            {
                                return true;
                            }
                        }
                    }
                }
            }
        }

        return false;
    }

2 个答案:

答案 0 :(得分:2)

首先,不需要冗余的嵌套循环,每个内部循环都不依赖于外部循环中的任何内容,因此不需要因为循环遍历而导致巨大的性能损失。字N ^ 3次(而不是3N)。

其次,我认为肯定有更优雅的方法(比如使用单词词典和计算字典中不包含的单词的最佳匹配,或其他更动态的方法),但它们会涉及更复杂算法。可以使用正则表达式来完成等效的简单方法:

// combine all the words into 1 string separated by a space
// where the confidence is high enough
// use a word that the regex's won't match for words where the confidence
// isn't high enough
var text = wordList.Select(w => w.Confidence >= 50 ? w.Text : "DONTMATCH")
           .Aggregate((x,y) => x + " " + y);

// now run the text through regular expressions 
// to match each criteria allowing for case insensitivity
// and known misidentifications
if (!Regex.IsMatch(text, @"abstract(in|m)g\s+(s|5)ervice\s+ordered", RegexOptions.IgnoreCase))
    return false;

if (!Regex.IsMatch(text, @"(d|o)ue\s+(d|o)ate\s+&", RegexOptions.IgnoreCase))
    return false;

if (!Regex.IsMatch(text, @"additional\s+comments\s+about\s+this", RegexOptions.IgnoreCase))
    return false;
return true;

由于您的算法只对一些特定的短语感兴趣,并且当单词的置信度太低时您不希望它匹配,我们可以轻松地将所有单词组合成一个由空格分隔的长字符串(为了方便)。然后我们构造正则表达式以满足已知替代品的3个感兴趣的短语,并且只针对正则表达式测试连接的字符串。

显然只是为了满足这个非常具体的案例......

答案 1 :(得分:1)

您可以尝试使用一些词汇,找到最接近Levenstein距离识别的词。

相关问题