

画像から直線を検出する方法としてハフ変換などがありますが、ライブラリを見る限り  
「一定の太さ以上の線のみ抽出する」といった指定方法が見当たりません。  
線の太さを考慮した直線検出の手法またはライブラリをご存知の方がいらっしゃいましたら、教えていただけると幸いです。  
  
言語と現在使用しているライブラリは以下のとおりです。  
＜言語＞ Java （Androidアプリ）  
＜ライブラリ＞ OpenCV 2.4.10  
  
  
【補足】  
対象画像は文字とその他オブジェクトが混在した白黒画像で、最終的には文字のみを抽出することが目的です。  
文字以外のオブジェクトが非常にやっかいで、英字のoと図形の○のように、文字との見分けがつきにくいノイズとなっています。  
強いて言えば、「文字は他よりも太い線で描かれている」という特徴があるため、今回の質問に至りました。  
  
文字抽出の処理自体はtesseract-ocrに任せるつもりですが、対象画像は  
・文字の位置がバラバラ  
・縦書きと横書きが混在  
・数種類のフォントサイズが混在  
と非常に面倒くさいもので、そのままOCRを行ってもまともな結果が得られません。  
そのため、OCR前に  
①画像から文字と思われるオブジェクトのみ抽出  
②大きさを基準にオブジェクトを整列（文章のような横書き形式）  
という前処理を施したいと考えています。  


CC BY-SA 3.0
2014-12-24T08:45:12.603
2484
2014-12-25T14:42:44.830
2014-12-24T10:14:22.853
5665
5665
question
java opencv
線の太さを考慮した直線検出


OpenCVの[膨張・収縮処理](http://opencv.jp/cookbook/opencv_img.html#id14)を行い、直線検出をする前に細い線を潰してしまうという方法があります。


CC BY-SA 3.0
2014-12-24T09:34:57.080
2491
2014-12-24T09:34:57.080
3639
2484
answer


ここでは、文字に対応する画素を「前景画素」と呼称して、一案を回答します。

ハフ変換で検出できる「直線」とは、簡単にいえば「 **直線的な前景画素の並び** 」です。

一方で、質問者さんがおっしゃる「太い線で書かれた文字」は、  
人間にとっては「太い線」かもしれませんが、  
画像上の画素の並び方でいえば、直線的な並びにはなっていないはずです。  
ですから、今回の問題の解法としてハフ変換は適していないと思います。

対象画像がどのようなものかわからないのでなんとも言えませんが、  
代わりに「 **前景画素が密集している** 」ことが文字領域の特徴になり得ませんか？  
コメントを見ますと漢字が比較的多いとのことですので、  
文字以外の図形がスカスカの疎な線で描かれているのであれば、  
前景画素の局所的な密度が使えそうな気がします。

具体的な処理例としては、  
テンプレートマッチングのように画像全体を適当な大きさのウィンドウで走査し、  
ウィンドウ内の前景画素数を数え、その数がウィンドウ面積の (例えば) 20% 以上であれば、  
その場所は文字領域であるとみなす、などという方法が考えられます。

* * *

## 追記

コメントを頂いた通り、上で例示した処理は重くなりがちです。  
幅・高さが W * H の画像全体を w * h のウィンドウで走査する場合、  
およそ (W * H) * (w * h) 回の画素参照が発生します。

ウィンドウ走査を高速化する常套手段としては、 計算を途中で打ち切る方法や画像を縮小する方法があります:

  * **計算を途中で打ち切る**
    * ウィンドウ内の前景画素を数えている途中で一定の数に達した場合、残りの画素を確認するまでもなく文字領域だと判定できる
    * 文字領域だと判定できた時点でカウントを打ち切る
  * **画像を縮小する**
    * 画像を縮小しても前景画素・背景画素の割合や位置関係は変わらない
    * 画像を縮小すればウィンドウも同じだけ縮小できる
    * 仮に画像とウィンドウを縦横それぞれ1/2倍すると、画素参照は1/16に減る


CC BY-SA 3.0
2014-12-24T14:23:14.223
2503
2014-12-25T14:42:44.830
2014-12-25T14:42:44.830
4962
4962
2484
answer