web-dev-qa-db-ja.com

OCRのフリーマンチェーンコードを理解する

私は自分の質問に対する答えを本当に探していることに注意してください。私はnotいくつかのソースコードまたはいくつかの学術論文へのリンクを探しています:私はすでにソースを使用していて、すでに論文を読んでいて、これの最後の部分をまだ理解していません問題...

私はいくつかの高速画面フォントOCRに取り組んでおり、非常に順調に進んでいます。

私はすでにベースラインを見つけ、文字を分離し、各文字を白黒に変換してから、フリーマンチェーンコードを適用するために各文字の輪郭を描きます。

基本的には、次のような8接続のチェーンコードです。

  3  2  1
   \ | /
  4-- --0
   / | \
  5  6  7

したがって、「a」がある場合、すべての変換(白黒への変換を含む)の後、次のようになります。

11110
00001
01111
10001
10001
01110

次に、外部カウントは次のようになります(Imayここで間違いを犯している、それはASCIIアートの輪郭であり、私の「アルゴリズム」は輪郭を間違っている可能性がありますしかし、それは私の質問のポイントではありません):

 XXXX
X1111X
 XXXX1X
X01111X
X10001X
X10001X
 X111X
  XXX

Xに続いて、チェーンコードを取得します。これは次のようになります。

0011222334445656677

これは正規化されたチェーンコードですが、チェーンコードはいつでも次のように正規化できます。最小の整数を保持するだけです。

(ちなみに、「X」の隣接する8つのピクセルを取得し、0がある場合は256のルックアップテーブルを調べるチェーンコードを見つけるための非常に効率的な実装があります、1,2,3,4,5,6または7)

しかし、今の私の質問は、その0011222334445656677チェーンコードから、「a」があることをどのように見つけるのですか?

たとえば、私の「a」が次のようになっている場合:

11110
00001
01111
10001
10001
01111  <-- This pixel is now full

その後、私のチェーンコードは次のようになります:0002222334445656677

それでも、これは「a」でもあります。

これらのチェーンコードの要点は、このような小さな変更に対応することですが、どの文字が1つのチェーンコードに対応するかをどのように見つけるかがわかりません。

私はそこまで行ってきました、そして今私は立ち往生しています...

(ちなみに、100%の効率は必要ありません。「0」を「O」や「o」と区別することなどは実際には問題ではありません)

28
SyntaxT3rr0r

必要なのは、チェーンコード間の距離を測定する関数dです。その後、特定のチェーンコードへの文字を見つけるのは簡単です。

入力:

  • 可能な文字のセットの正規化されたチェーンコードS(通常、A-Z、a-z、0-9、...のカインコード)
  • 検出する必要があり、わずかに変形する可能性のある文字のチェーンコードx(チェーンコードはセットS内のどのチェーンコードとも一致しません)

アルゴリズムは、可能なチェーンコードのセットを反復処理し、各要素の距離d(x,si)を計算します。距離が最小の文字がアルゴリズムの出力になります(識別された文字)。

次のことをお勧めします距離関数:2つのチェーンコードの場合、各方向の長さの違いを合計します:d(x,si) = |x0-si0| + |x1-si1| + .. + |x7-si7|x0はチェーンコードxの0の数、si0はチェーンコードsiの0の数などです。

例は私が考えていることをよりよく説明します。次の画像には文字8、B、Dがあり、4番目の文字はわずかに変形した8であり、識別する必要があります。文字はフォントサイズ8のArialで書かれています。画像の2行目は、ピクセルを見やすくするために10倍に拡大されています。

enter image description here

正規化されたチェーンコードを手動で計算しました(うまくいけば正しいです)。

8:  0011223123344556756677
B:  0000011222223344444666666666
D:  00001112223334444666666666
8': 000011222223344556756666 (deformed 8)

長さの違い(絶対)は次のとおりです。


direction | length         | difference to 8'
          | 8 | B | D |  8'|   8 |  B |  D |
----------+---+---+---+----+-----+----+-----
        0 | 2 | 5 | 4 |  4 |   2 |  1 |  0 |
        1 | 3 | 2 | 3 |  2 |   1 |  0 |  1 |
        2 | 3 | 5 | 3 |  5 |   2 |  0 |  2 |
        3 | 3 | 2 | 3 |  2 |   1 |  0 |  1 |
        4 | 2 | 5 | 4 |  2 |   0 |  3 |  2 |
        5 | 3 | 0 | 0 |  3 |   0 |  3 |  3 |
        6 | 3 | 9 | 9 |  5 |   2 |  4 |  4 |
        7 | 3 | 0 | 0 |  1 |   2 |  1 |  1 |
----------+---+---+---+----+-----+----+-----
                        sum   10 | 12 | 14 |

8'8のチェーンコードまでの距離が最小であるため、アルゴリズムは文字8を識別します。文字Bまでの距離はそれほど大きくありませんが、これは変形した8がBのように見えるためです。

この方法は、スケーリング不変ではありません。これを克服するための2つのオプションがあると思います。

  • さまざまなフォントサイズの場合、正規化されたチェーンコードのセットが異なります
  • 大きなサイズ(35x46ピクセルなど)で正規化されたチェーンコードの1セットで、入力文字(識別が必要)をこの大きなサイズにスケーリングします。

距離関数がすべての英数字のセットに十分であるかどうかはよくわかりませんが、そう願っています。文字を識別する際のエラーを最小限に抑えるために、分類ステップにその他の機能(チェーンコードだけでなく)を含めることができます。また、距離の測定が必要になります。今回は特徴ベクトル用です。

18
Christian Ammer

あなたの質問は十分に具体的ではないので(チェーンコードに基づく完全なアルゴリズムが必要なのか、それとも確率的な分類が必要なのか)、問題について私が知っていることをお話しします。

チェーンコードを使用すると、シンボルのいくつかのプロパティをカウントできます。 344445、244445、2555556、344446(任意の数の4)の形式の回転の数、つまり文字の「スパイク」。チェーンコードに次のような3つのセクションがあるとします。だから、これはほぼ間違いなく「W」です!しかし、これは良いケースです。さまざまな種類の回転の数を数え、それを以前に保存したすべての文字の値と比較できます(手動で行います)。これは非常に優れた分類子ですが、もちろんそれだけでは十分ではありません。 「D」と「O」、「V」と「U」を区別することは不可能です。そして、多くはあなたの想像力に依存します。

参照を使用していくつかの文字の画像のテストケースを作成することから始め、変更と新しい基準の発明の間でアルゴリズムを確認する必要があります。

これが少なくとも部分的にあなたの質問に答えることを願っています。

更新:1つの明るいアイデアが頭に浮かびました:)チェーン内の単調なシーケンスの数を数えることができます。たとえば、チェーン000111222233334443333222444455544443333(簡単な例ですが、実際には手紙)私たちは持っています
011122223333444 3333222444455544443333、
00011122223333444 33222 444455544443333、
000111222233334443333222 4444555 44443333、
0001112222333344433332224444555 444433

つまり、4つの単調なサブシーケンス。

これは良い一般化であるはずです。実際の文字のこの変更の数を数え、検出されたチェーンから取得したものと比較するだけです。これは良い試みです。

いくつかの問題とアイデア:

  1. チェーンはある意味で循環的であるため、チェーンの両端で単調さを検出することに対処する必要があります(1つずつのエラーを回避するため)。
  2. 一部のアーティファクトを考慮する必要があります。たとえば、文字が十分に大きいことがわかっている場合(たとえば、高さが20ピクセル)、3項目より短い単調な中断を無視する必要があります。たとえば:)
3
unkulunkulu

先月、私は同じ問題に取り組んでいました。今、私はvetexチェーンコードによってこの問題を解決しました。

Vetexチェーンコードはバイナリチェーンコードです。次に、5つにカットします。明らかに、0〜9の数字には、さまざまな部分に独自の文字があります。

0
xu2mao

チェーンコードを、トポロジーを伝達するさらに単純なモデルに変換してから、機械学習コード(おそらくPrologで記述される)を実行することができます。

しかし、私はそれを支持しません。人々はこれを何年も行ったり試したりしてきましたが、まだ良い結果は得られていません。

この非線形/しきい値ベースのアプローチで時間を無駄にする代わりに、相関に基づくロバスト手法を使用してみませんか?最も簡単なのは、テンプレートを使用することです。

しかし、私は文字にガボールウェーブレットを作成し、係数をベクトル空間に並べ替えます。 サポートベクターマシンをいくつかの例でトレーニングし、それを分類器として使用します。

これは私たちの脳がそれを行う方法とほぼ同じであり、コンピューターでそれが可能であると確信しています。

いくつかのランダムなチットチャット(無視):

神経回路網は理解できないので好きではないので使いません。しかし、私は常にGeoff Hintonsグループの仕事に感銘を受けています http://www.youtube.com/watch?v=VdIURAu1-a

どういうわけか、彼は情報を逆方向に伝播できるネットワーク(ディープラーニング)に取り組んでいます。彼が訓練された数字認識ネットワークに夢を与えるという彼の話があります。つまり、彼は出力ニューロンの1つを「2」に設定し、ネットワークは入力ニューロン上に2つあると考えるものの画像を生成します。

これはとてもかっこいいと思いました。

0
whoplisp