1

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

因此,有时它会将“S”与“5”或“l”与“1”混淆。此外,它不考虑大小写。所以我必须搜索这两种情况。

它的工作方式是我在纸上搜索某些彼此接近的单词。所以第一组词[I]是“Abstracting Service Ordered”。如果页面包含彼此相邻的这些单词,则它会移动到下一组单词 [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;
    }
4

2 回答 2

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 个感兴趣的短语,并针对正则表达式测试连接的字符串。

它显然只是为了迎合这个非常具体的情况......

于 2013-07-11T16:17:00.760 回答
1

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

于 2013-07-11T16:20:37.577 回答