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

まず、冗長な入れ子ループは必要ありません。各内部ループは外部ループの何にも依存しないため、(3N ではなく) N^3 回の単語のループによるパフォーマンスの大幅な低下は必要ありません。

第二に、より洗練されたアプローチ (単語の辞書を使用し、辞書にない単語のベストマッチを計算する、または他のより動的なアプローチなど) は間違いなくあると思いますが、より複雑なアルゴリズムが必要になります。同等のものへの簡単なアプローチは、正規表現を使用して実行できます。

// 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;

アルゴリズムはいくつかの特定のフレーズにのみ関心があり、単語の信頼度が低すぎる場合は一致させたくないため、すべての単語をスペースで区切られた 1 つの長い文字列に簡単に結合できます (便宜上)。次に、関心のある 3 つのフレーズに対応する正規表現を、既知の選択肢で構築し、正規表現に対して連結された文字列をテストするだけです。

明らかに、この非常に特定のケースにのみ対応する予定です...

于 2013-07-11T16:17:00.760 に答える
1

いくつかの語彙を使用して、Levenstein Distance によって認識される単語に最も近い単語を見つけることができます。

于 2013-07-11T16:20:37.577 に答える