2

スキャンした画像 (PNG またはその他の便利な画像形式を想定してみましょう) を取得し、それを多くの小さな画像に分割するプログラムによる方法が必要です。スキャンされた画像はグリッドであり、グリッドのボックスは常に同じサイズで同じ相対位置にあります。イメージはスキャンされるため、必ずしも同じ絶対位置にあるとは限りません。各ボックスには文字があります。理想的には、ボックスの境界線なしで、文字を独自の画像ファイルとして保存したいと思います。

私は PHP と ImageMagick を好みます。これは、ツールの適切な組み合わせになると思います。ただし、もっと良い方法があれば柔軟に対応します。

4

1 に答える 1

5

これが問題へのアルゴリズム的アプローチの始まりです...

テスト目的で作成したbox.jpg、352x232ピクセルのサイズの画像を使用しています。

テスト画像...

目標は、赤いボックスを識別し、「デイブ」の画像を抽出することです。

私のアルゴリズムのアプローチは次のようになります。

  1. 画像を元の幅で、高さが1ピクセルしかないものに拡大縮小します。同時に、グレースケールに変換してコントラストを上げます。ImageMagickが出力できる各ピクセルのプロパティのテキストによる説明を使用します。このようにして、垂直の赤い線のピクセルが極端な色の値を蓄積した2つのスポットを見つけることができるはずです。(垂直の赤い線のピクセルと灰色の文字のピクセルは、より一般的な色の値になります。)

  2. 他の方向でも同じようにします。画像を元の高さで幅が1ピクセルしかないものに拡大縮小します(グレースケールに変換し、コントラストを上げ、テキストによる説明を使用します... yadda-yadda)。水平の赤い線のピクセルが極端な色の値を蓄積した2つのスポットを見つけることができます。(灰色の文字ピクセルと組み合わされた垂直の赤い線は、より「平均的な」色の値になります。)

  3. 2つの結果のそれぞれで、各カラー値のピークの位置を特定します。これにより、元の画像から抽出するサブ画像のジオメトリが得られます。

  4. 元の画像からサブ画像を抽出します。必要に応じて両側をトリミングします。

完全なアルゴリズムを詳しく説明することはできませんが、手順1と2で使用するコマンドは次のとおりです。

ステップ1のコマンド

convert                   \
    -type grayscale       \
    -depth 8              \
     box.jpg              \
    -scale x1\!           \
    -contrast-stretch 6x6 \
     columns.txt

ステップ1の結果

これはの内容ですcolumns.txt

 # ImageMagick pixel enumeration: 352,1,255,gray
 0,0: (  0,  0,  0)  \#000000  black                 <-- left outer image border 
 1,0: (253,253,253)  #FDFDFD  gray(253,253,253)
 2,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 3,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 [...]
 20,0: (255,255,255)  #FFFFFF  white
 21,0: (255,255,255)  #FFFFFF  white
 [...]
 46,0: (255,255,255)  #FFFFFF  white
 47,0: (255,255,255)  #FFFFFF  white
 48,0: (243,243,243)  #F3F3F3  gray(243,243,243)
 49,0: (  0,  0,  0)  #000000  black                 <-- left box border (ex-red)
 50,0: (  0,  0,  0)  #000000  gray(0,0,0)           <-- left box border (ex-red)
 51,0: (  0,  0,  0)  #000000  black                 <-- left box border (ex-red)
 52,0: (  0,  0,  0)  #000000  black                 <-- left box border (ex-red)
 53,0: (221,221,221)  #DDDDDD  gray(221,221,221)
 54,0: (231,231,231)  #E7E7E7  gray(231,231,231)
 55,0: (236,236,236)  #ECECEC  gray(236,236,236)
 [...]
 247,0: (236,236,236)  #ECECEC  gray(236,236,236)
 248,0: (216,216,216)  #D8D8D8  gray(216,216,216)
 249,0: (  0,  0,  0)  #000000  black                <-- right box border (ex-red)
 250,0: (  1,  1,  1)  #010101  gray(1,1,1)          <-- right box border (ex-red)
 251,0: (  0,  0,  0)  #000000  black                <-- right box border (ex-red)
 252,0: (  1,  1,  1)  #010101  gray(1,1,1)          <-- right box border (ex-red)
 253,0: (226,226,226)  #E2E2E2  gray(226,226,226)
 254,0: (244,244,244)  #F4F4F4  gray(244,244,244)
 255,0: (244,244,244)  #F4F4F4  gray(244,244,244)
 [...]
 303,0: (255,255,255)  #FFFFFF  white
 304,0: (255,255,255)  #FFFFFF  white
 305,0: (255,255,255)  #FFFFFF  white
 [...]
 342,0: (255,255,255)  #FFFFFF  white
 343,0: (255,255,255)  #FFFFFF  white
 344,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 345,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 346,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 347,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 348,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 349,0: (255,255,255)  #FFFFFF  gray(255,255,255)
 350,0: (253,253,253)  #FDFDFD  gray(253,253,253)
 351,0: (  0,  0,  0)  #000000  black                <-- right outer image border

: ImageMagickが時々、時々の色の値を呼び出すこと、そして#FFFFFF時々white、時々の色の値を呼び出すことは少し混乱しているようです...たぶんバグですか?とにかく、ここで私たちをブロックしません...)gray(255,255,255)#000000blackgray(0,0,0)

ステップ2のコマンド

convert                   \
    -type grayscale       \
    -depth 8              \
     box.jpg              \
    -scale 1x\!           \
    -contrast-stretch 6x6 \
     rows.txt

ステップ2の結果

これはの内容ですrows.txt(今回は紛らわしい色の名前を削除しました):

 # ImageMagick pixel enumeration: 1,232,255,gray 
 0,0: (  0,  0,  0)  #000000                 <-- top outer image border
 0,1: (255,255,255)  #FFFFFF  
 0,2: (255,255,255)  #FFFFFF  
 0,3: (255,255,255)  #FFFFFF       
 0,4: (255,255,255)  #FFFFFF       
 0,5: (255,255,255)  #FFFFFF       
 0,6: (255,255,255)  #FFFFFF       
 0,7: (255,255,255)  #FFFFFF       
 0,8: (255,255,255)  #FFFFFF       
 0,9: (255,255,255)  #FFFFFF       
 0,10: (255,255,255)  #FFFFFF       
 [...]
 0,46: (255,255,255)  #FFFFFF       
 0,47: (255,255,255)  #FFFFFF       
 0,48: (240,240,240)  #F0F0F0       
 0,49: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,50: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,51: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,52: (  0,  0,  0)  #000000                <-- top box border (ex-red)
 0,53: (225,225,225)  #E1E1E1       
 0,54: (234,234,234)  #EAEAEA       
 [...]
 0,207: (244,244,244)  #F4F4F4       
 0,208: (230,230,230)  #E6E6E6       
 0,209: (  0,  0,  0)  #000000               <-- bottom box border (ex-red) 
 0,210: (  0,  0,  0)  #000000               <-- bottom box border (ex-red)
 0,211: (  0,  0,  0)  #000000               <-- bottom box border (ex-red)
 0,212: (  0,  0,  0)  #000000               <-- bottom box border (ex-red)
 0,213: (234,234,234)  #EAEAEA       
 0,214: (245,245,245)  #F5F5F5       
 [...]
 0,229: (255,255,255)  #FFFFFF       
 0,230: (255,255,255)  #FFFFFF       
 0,231: (  0,  0,  0)  #000000               <-- bottom outer image border

これらの2つの結果から、次のように確実に結論付けることができます。

  1. 左側の垂直の赤いボックスの境界線は、ピクセル列49〜52にあります。
  2. 右側の垂直の赤いボックスの境界線は、ピクセル列249〜252にあります。
  3. 上部の水平の赤いボックスの境界線は、ピクセル行49〜52にあります。
  4. 下の水平の赤いボックスの境界線は、ピクセル行209〜222にあります。
  5. 1.と2から、197の赤いボックスの「内側の幅」(249から52を引いたもの)を計算できます。次に、抽出されたサブ画像の幅に196を使用しましょう。
  6. 3.と4から、157の赤いボックスの「内側の高さ」(209から52を引いたもの)を計算できます。次に、抽出されたサブ画像の高さに156を使用しましょう。
  7. 切り抜きの水平オフセットは52ピクセルである必要があります。53を選びます。
  8. 切り抜きの垂直オフセットは52ピクセルである必要があります。53を選びます。

したがって、元のサブイメージからサブイメージを切り取るコマンドは次のようになります。

convert  -crop 196x156+53+53  box3.jpg  sub-box.jpg

または、画像のサイズをこのWebページの白い背景と区別しやすくするには:

convert  -crop 196x156+53+53  box3.jpg  -colorize 20,0,20  sub-box.jpg

結果の画像:
ここに画像の説明を入力してください

これで、画像にOCRを適用できます。

tesseract sub-box.jpg OCR-subbox 1>/dev/null && cat OCR-subbox.txt

  Dave
于 2012-08-16T12:55:55.173 に答える