下面是一个函数,它使用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;
}
答案 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距离识别的词。