OpenCVで画像(申請書などの書類)から点線を検出して直線に置き換えたいのですが、そのようなことは可能でしょうか?
言語はC++、OpenCVは2.4.13を使っています。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
画像の具合や,画像だけ指定したら全自動なのか,対話的に何か指定していいのか,とかによると思います.そういう前提の話一切無しだと,答えは(不可能とは言い切れないという意味で)「頑張ればできるんじゃない?」にしかならないように思います.
画像はユーザーがどのような書類を持ってくるかにもよりますが、PDFで作られた書類やスキャナで取り込んだ書類が多いと思います。
点線の検出は全自動でやりたいです。

回答1件
0
ベストアンサー
可能でしょうか?
と問われれば,「不可能とは言い切れない」が答えにならざるを得ないと思います.
どんな絵が処理対象となるのか?という範囲が定まらないうちは,妥当な処理を考えることも難しいでしょうが,
「点線」を構成する「点」なり「短い線」なりを検出し,それらの並びを認識するような処理になるのではないかと推測します.
- 対象が「----」のような「短い線」の連続で有る場合,個々の「短い線」から方向に関する情報が得られるので,「エッジの追跡」とか「エッジの連結」のような処理について調べると有用かもしれません.
- 画像を(「点線」を構成する要素が失われない方法で)縮小する,という手もあるでしょう.
(縮小画像上で繋がることを判定のヒントにする) - 点線の切れている部分(点と点の間)の短さ次第では,簡便にモルフォロジ処理で埋められるかもしれません.
- ハフ変換的な投票ベースの方法もあると思います.
(「書類」の画像の具合次第ですが,「処理対象は罫線的なものなので縦線か横線しか無い」的な知識を利用できたりとか?)
投稿2019/07/23 09:45
編集2019/07/23 09:52総合スコア12203
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
申請書などで氏名欄がカナと漢字の2つに点線で分かれていますよね?
ああいう点線を直線にしたいです。
なんとなく想像は付きますが…
具体データや実施結果が存在しない現状では,「ここで挙げたような方法で割とできるのでは?」という雰囲気(?というか)以上のレベルで話を詰めるのは難しいと思います.
何はともあれ,実際に問題に取り組んでみてください.
そして,そこで発生した具体的な解決し難い問題等に関して,改めて質問されるのが良いかと思います.
エッジの追跡やエッジの連結は調べてみましたが点線の認識につながりそうなヒントは見つけられませんでした。
ハフ変換(cv::HoughLines)は使ってみましたが、点線が途中までしか認識されず、何もなかった場所に余分な線が引かれたりして使えませんでした。
モルフォロジ処理については今調べているところです。
「点線」を構成する要素が失われない方法で画像を縮小する具体的なやり方を教えてもらえないでしょうか?
> エッジの連結
点線を1本の線にすることは,エッジ検出時に断片化したエッジを1本に繋ぐ系の処理と似ていると思ったのですが,ググってもそれ系の話は意外と見つからないですね…不思議.
> ハフ変換
cv::HoughLines等を何の工夫もなく使ってもあまりうれしい結果を得るのは難しいです.
(故に,私は「的な投票ベースの…」と書いています.)
> 縮小の具体的なやり方
具体的な問題が見えていない第三者からは具体的な方法は言えない的な旨を既述したつもりなのですが…
例えば,2x2[pixel]のサイズの絵を縦横半分(1x1)に縮小する場合,縮小結果の画素の色は何色にすべきでしょうか?
元画像の4つの画素のうちのいずれか1つの色を採用するのでしょうか?
それとも4画素の色の平均を求めてそれを結果とするのでしょうか?
色々な方法が考えられますが,どういう方法が良いかは縮小の用途次第ですよね.
今回の場合であれば「点線の色」が失われにくい方法にすれば良いのでは?という話です.
「大抵は線が背景よりも暗い」と言えるならば,例えば,前記の2種の方法よりも「4画素のうち最も暗い画素の色を採用する」という方法を考えることができるかもしれません(意味的にはモルフォロジに近い話になる)し,
画像上の点の具合次第では「元の画像において小さな領域を構成する画素の色を優先して採用する」という方法が有効なのかもしれません.
あるいは「主要なエッジ勾配方向を示す画素の色を採用」したら何か良いことがあるかもしれません.
>cv::HoughLines等を何の工夫もなく使ってもあまりうれしい結果を得るのは難しいです.
>(故に,私は「的な投票ベースの…」と書いています.)
>
cv::HoughLinesの第5引数である、投票数を意味するしきい値はいろいろ変更して試してみましたが、そういうことではないですか?
例えば前もって(問題の定義だったり,前処理の結果だったりによって)検出すべき線が「横線」だとわかっているとしたら,私なら,画像の縦幅分に相当するサイズの投票用バッファを用意して,そこに何らかの量を投票するような処理を実装すると思います.
cv::HoughLines()という既存関数をどうにかして使うという話ではなく,方法を考えて実装して検討するという話です.
もちろん,cv::HoughLines()の引数なりをどうにか調整することであなたが今現在考えて検討しようとしている処理内容と同一の意味の処理を実施できる可能性も有り得ますが,それが可能か否か?あるいは「これでそうなると思うのだけど結果が伴わない→why?」といった事柄に直面しておられるならば,その範囲に話を絞った質問を別途行うことで広く意見を募ることを勧めます.
(その際は,具体的なデータ:サンプル画像やそれに対する処理結果 を示してください.そうじゃないと,この質問と同程度の「ぼんやりした」話になってしまうことと危惧します.)
検出すべき点線が縦線なのか横線なのか、どこにあるのかは全く分からない状態で検出できる必要があります。
縮小についてはcv::resize()で5種類の方法があり、全部試したところ線がつながりやすい縮小方法もありましたがかなり(30%くらい)縮小する必要があり、それだと精度的に他の部分で問題になり使えませんでした。
もっと絞った質問をしたいところですが、今のところ可能性がありそうな方法を見出すことができず最初のぼんやりとした質問の状態から抜け出せていません。
縮小した世界で線を検出できるのならば,その情報は,元の(100%サイズの)絵の上で線を見つけるための有力なヒント(画像のどこにどんな向き/長さの線がありそうかという情報)になるわけですが……果たして?
(一体どこの部分で精度問題が発生するのかは全くこちらには不明ですけども,画像縮小は線を見つけるための工夫でしかないので,縮小した世界でその他全ての処理を行わなくても良いのですよ?)
縮小することで点線を直線にできても、その線の座標は分からないですよね?
あらためて直線を検出して座標を得るということになるでしょうか?
しかしHoughLinesはなにもない場所にまで線が引かれてしまい精度が悪くて使えないです。私の使い方が問題でしょうか?
他に直線を検出する方法はありますか?
「点線」の話以前に,「(切れてない)線」の検出方法が問題になるとは思っていませんでした.
切れてないなら,原始的には(端点なりコーナーなりから出発して)着目画素の隣→そのまた隣→… と繋がっている画素を追って行って,その形状が直線的か否かで判断すれば良いのではないでしょうか.
あるいは今現在のHoughLineの結果として,「間違った結果もたくさん出てくるけども,欲しい線もちゃんと見つかってはいる」的な状況になっているならば,HoughLineの結果を鵜呑みにせずに絞り込めば良いでしょう.
ハフ変換の結果は「(無限)直線」だけど,そうじゃなくて「線分」のデータが得たい,というなら,元画像上でその直線に所属する点群を探索して端点を見つけるような後処理を設ければよいでしょうし,または,「確率的ハフ変換」(HoughLinesじゃなくてHoughLinesP)というのを使うと何か良いことがある可能性もあります.
コメントだけでだらだらと続きすぎているので,一旦切り上げませんか?
(何度か同様の事柄を述べていますが)線の検出の方法が問題になっているならば,「線の検出の方法」を主題とした質問を立てると良いと思います.)
私は(このサイトの機能で通知が来るために)このコメント欄を能動的に見に来ているわけですが,他の人々の目には触れていない可能性が高いと思うのです.
別途質問にすることで,より知識と経験を持つ人々からのアドバイス等が得られる可能性が高まります.
了解です。
とりあえず今までに頂いたヒントを元にもう少し頑張ってみます。
いったんここまででクローズということでfanaさん、ありがとうございました。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。