一角獣は夜に啼く

ただの日記です。

思ってることとか考えたこととか適当に書きます。 主にソフトウェア開発の話題を扱う 「ひだまりソケットは壊れない」 というブログもやってます。

画像の中の重要そうな場所を特定する方法を考えたりしてる

何か画像があったとして、その画像を指定の大きさにサイズ変更したいことってあると思うんですが、元画像のサイズと目標サイズのアスペクト比が違う場合なんかは単に画像を拡大縮小するだけじゃなくて、一部を切り抜いたりしないとだめなわけです。 で、その時の切り抜く位置をどう決めるのがいいんだろうなー、ということを思ったりしてるのです。

多分一番単純な方法は、画像の内容によらず中央寄せにするとか左上寄せにするとかだと思います。 ただ、それだと画像の内容によっては全然意味のない箇所を切り抜いちゃったりするので、できれば画像の内容を見て切り抜く位置を決定したいなーという感じ。

今日は、画像のエッジを抽出して、エッジが多く含まれる箇所を重要そうであるとみなすようにするということを考えたりしました。

サンプル

まず、画像からエッジを検出します。 今回は OpenCV を使い、Canny のアルゴリズムでエッジ検出しました。 そして、画像を一定サイズ (今回は縦 30 px、横 30 px とした) ごとのブロックに分け、ブロックごとのエッジの密度 (?) を計算して、大きいところを濃い赤色にする、というようなことをしてみました。


f:id:nobuoka:20131024003410j:plain
人物とテロップ。 これは文字と人物の部分が濃い赤になってて良い感じです。


f:id:nobuoka:20131024003909j:plain
木と人物。 これは足元の方が濃くなってしまっていて、まあアルゴリズム的には当然そうなるのですが望ましくない結果です。 根っこに凹凸があってエッジとして検出されやすいのかなと思いました。


f:id:nobuoka:20131024003825j:plain
商品広告画像。 文字部分が赤くなっているのは良さそうではあるけど、次の画像と同じく端末部分がほとんど暗くなってしまっているのは微妙。


f:id:nobuoka:20131024003803j:plain
商品広告画像。 端末の縁の部分はエッジとして検出されてはいるものの、画面中央はまったくエッジがないわけなので赤くなっていません。 ブロックごとのエッジの密度を見るのは簡単ではありますが、こういう結果を見るとちゃんとエッジを曲線として扱って、物体全体を認識するようにできた方がちゃんと検出はできるだろうなぁと思ったり。


f:id:nobuoka:20131024003626j:plain
大きな文字と小さな文字。 本来的には大きな文字の方が重要なはずですが、文字が小さい方が単位面積あたりのエッジ部分が多いので小さい文字の方が濃い赤になってしまっています。


f:id:nobuoka:20131024003540j:plain
2 次元 (?) 画像。 人物部分が濃い赤になっていて良さそうです。

まあ悪くはないけど、って感じかなぁ

適当に最近公開された記事に含まれる画像を 200 件ほど試してみましたが、画像の内容を見ずに中央寄せとか左上寄せとかで画像を切り抜くよりは、エッジの密度を見た方が良い検出ができるんじゃないかなぁという印象です。 とはいえめっちゃ使えるかっていうとそうでもない感じですね。

詳しい人教えてください><

画像処理系全然詳しくないのでどういう手法があるかなど全然分かんないんですが、「そういうのはこうしたらいいんだよ!」 みたいな情報があったら教えてください!!!