4

スキャンしたドキュメントから、OCRエラーの可能性があるキーワードを特定したいと思います。スキャンされたドキュメントの各文字とその代替のキーワードと信頼値のリストに基づいて、信頼できるキーワードを識別するためのアルゴリズムをどのように開発できますか?

OCRには、各キャラクターとその最良の選択肢の信頼値を提供するTesseractを使用しています。したがって、すべての単語について、次のようなリストがあります。

 Word=order
 [0] o (93%) [alts: 0 (90%), c (83%), e (82%)]
 [1] r (96%)
 [2] d (96%)
 [3] e (90%) [alts: a (75%)]
 [4] r (95%) 

OCRエラーを含む別の例:

 Word=PaYmeHI (Payment would be correct)
 [0] P (81%) [alts: p (78%), D (68%)]
 [1] a (76%) [alts: 3 (73%), e (63%), ö (61%)]
 [2] Y (87%) [alts: V (86%)]
 [3] m (83%) 
 [4] E (71%) [alts: € (79%), 9 (72%), % (67%), e (65%), B (64%), G (64%)]
 [5] H (76%) [alts: n (83%), D (74%), N (70%), ü (69%)]
 [6] I (75%) [alts: t (69%), { (67%), 1 (65%), i (61%)]

ご覧のとおり、tesseractは常に最高のパーセンテージ(4、5)の結果を選択するとは限りません。

スキミングから結果まで、90%を超える値を持つほとんどの文字が正しいように見えます。ただし、悪い結果には、選択肢のリストに正しい文字が含まれているとは限りません([2]を参照してください。これは小文字である必要があります)y

現在、レーベンシュタイン距離と文字列の長さを使用して候補のリストを取得しています。さらに、キーワードを除外していlev2 > 3ます。しきい値を決定するための良い方法をまだ探しているので、これはハードコーディングされています。

      int lev = getLevenshteinDistance(keyword, s);
      int lev2 = getLevenshteinDistance(keyword.toLower(), s.toLower());
      int len = Math.abs(keyword.length - s.length); 
      int x = lev + lev2 + len;

x最も可能性の高い結果を得るために、キーワードのリストをで並べ替えています。

そこでまず、OCRの結果と文字列の長さに基づいて適切なしきい値を決定する方法を探しています。短い文字列は、大きな文字列よりも低いしきい値を必要とし、OCRの結果も確実になります。上記の例を見てください。語順については、lev2 <= 1で十分ですがpayment、少なくともlev2 <= 3については計算する必要があります。

次に、残った候補の1つが実際に単語と一致するかどうかをどのように判断できますか?lev == 0すべてのキャラクターの信頼値が正しい場合と>= 90それは明らかです。しかし、悪いOCRの結果を考慮すると、代替のOCRの選択肢も含む、どのアルゴリズムを開発できますか?

4

2 に答える 2

2

私は自分のプロジェクトに似たようなことを考えていました。私はまだ良い答えを持っていませんが、ここにいくつかの考えがあります:

私たちが答えようとしている質問はこれだと思います:

このドキュメント(OCR結果)には「注文」という用語が含まれていますか?

アイデア1

OCRドキュメントには、いくつかの「スコア」を含む用語が含まれています...

したがって、あなたの例では、ドキュメントには次のものが含まれています。

  • スコア=合計(93,96,96,90,95)/ 5=94の順序
  • 0rder with score = sum(90,96,96,90,95)/ 5 = 93
  • スコア=合計(83,96,96,90,95)/ 5=92のcrder
  • スコア=合計(82,96,96,90,95)/ 5=91のerder
  • スコア=合計(93,96,96,75,95)/ 5=91のオーダー
  • 0rdar、スコア= sum(90,96,96,75,95)/ 5 = 90
  • スコア=合計(83,96,96,75,95)/ 5=89のcrdar
  • スコア=合計(82,96,96,75,95)/ 5=88のエルダー

各候補のスコアが得られたので、クエリを指定してドキュメントのスコアを取得できます(今のところレーベンシュタイン距離を使用しています...)

キーワード「order」が与えられたドキュメントのスコアは、

  • (3-min(lev(order、order)、3)* 0.33)* 94、
  • (3-min(lev(0rder、order)、3)* 0.33)* 93、
  • (3分(lev(crder、order)、3)* 0.33)* 92、
  • ...、
  • ..。

このスコアがあるしきい値よりも高い場合、ドキュメントは「順序」に一致すると見なされます

アイデア2

一部の言語モデルでOCRの結果を改善できます

次のように各用語のスコアを計算します。

term        | ocr_score   |ngram score            |combined score
------------+-------------+-----------------------+---------------
order   | 94          |score(ord, rde, der)   |ocr*ngram
0rder   | 93          |score(0rd, rde, der)   |ocr*ngram
crder   | 92          |score(crd, rde, der)   |ocr*ngram
erder   | 91          |score(erd, rde, der)   |...
ordar   | 91          |score(ord, rda, der)   |...
0rdar   | 90          |score(0rd, rda, der)   |...
crdar   | 89          |score(crd, rda, der)   |...
erdar   | 88          |score(erd, rda, der)   |...

ここで、score(ord)='ord'のトリグラム確率

たとえば、Googleブックスでは、任意のトリグラムのトリグラム確率が示されます( http://books.google.com/ngrams/chart?content=ord&corpus=0&smoothing=3&year_start=1970&year_end=2000を参照) 。

ユニグラム、バイグラム、クワッドグラムを計算することもできます...; 次に、単語自体の「ユニグラム」確率に基づいてスコアを計算できます。単語のバイグラムなど...; 次に、純粋に分析的な言語モデルを適用することもできます

これで、「候補用語」ごとにスコアが増え、それらすべてをスコアごとにいくつかの重みと組み合わせて、用語の合計スコアを取得します。

アイデア3

さて、上記は用語/スコアの爆発的な増加につながります...これは計算集約的です。そのため、いくつかの魔法を使用して、アイデア1と2に基づいて各用語の確率的DFAを作成します。ドキュメントには、用語ではなく確率的DFAが含まれるようになりました。Luceneの連中は、レーベンシュタインDFAを構築し、DFA1とDFA2がすぐに一致するかどうかを確認できるようにするためにいくつかの作業を行いました...

于 2012-05-02T20:51:18.523 に答える
1

まず第一に、あなたのプログラムはあなたにP(記号|観察)ではなくP(観察|記号)を与えていると思います。P(シンボル|観測)\比例P(観測|シンボル)* P(シンボル)。

たとえば、支払いのeの場合、観測されたパターンがシンボルを与える確率はユーロで最も高かったものの、ユーロを観測する確率は非常に小さいです。したがって、ユーロではなく「e」である可能性が最も高くなります。

したがって、私の提案は、すべての可能な単語のlog(P(observation | symbol)* P(symbol))を合計し、この値を最大化する単語を選択することです。

さらに、P(symbol)を使用する代わりに、コンテキストを使用してより正確な見積もりを使用できます。

于 2012-05-02T18:59:17.030 に答える