ハフ変換を使わない画像のエッジ角度(書きかけ)
エッジの角度を求めたり、直線を検出して、その角度を求めるためには、ハフ変換がよく使われます。 ただ、極座標がイマイチ好きになれないので(おいおい)もっと簡単な方法はないかと考えておりました。 特徴点を求めるところで思いついた、エッジの角度を足していけば何とかなるのではという実験が本ページの内容です。
[写真1]エッジ検出のための画像
この画像は、PaintShopProを使って、四角形を20度まわしたものです。 このグラフィックから、直線に直交する角度として、70.233度が求められました。 この画像がたまたまよい結果を生んだだけで、悪化する可能性もあります。 所要時間は、640x480の画像に対して、32msでした。(Atheron 2400+/512M/Watcom[Ox]) エッジを多数含んでいる画像の場合、もっと遅くなるものと思われます。
3×3の深い世界
画像処理で何か行うときに、3×3や5×5といった領域からある種の計算を行い、その結果を使うことはよくあります。
エッジ検出(微分)なんかもその典型です。
ただ、一般的にはフィルタとして、1つの情報を得るケースが多いようです。
(私が知らないだけで、やっておられる方がきっとおられるのでしょう)
今回は、3×3要素から、直線エッジに垂直で明るい方向を向くベクトルを作ってみます。
といっても、やっていることは、とても単純で、3×3のうち、右3要素の輝度合計から、左3要素の輝度合計を引いたものをX成分、同様に下3要素輝度合計から上3要素輝度合計を引いたもの(画面座標系なので、Y軸は下方向に正としています。数学系がよければ、上から下を引いてください)をベクトルとしているだけです。
このベクトルは、prewitt一次微分パラメータとして知られているものです。
こんなショボい(?)ベクトルでも、かなりイイ角度に向きます。(下に、これを1度ごとに分けて投票した結果の抜粋を書いています)
計算数を減らすために、エッジ上にいるかどうかを、上下左右4画素との輝度差絶対値の合計で「脚きり」し、
さらに、求めたベクトル絶対値が低い場合も「脚きり」しています。このうち、後段の脚きりは、速度もほとんど変化がなく、やめた場合、70.233度まで、成績があがりました。
投票数
各角度を1度ごとに分割し、投票処理を行います。
上のサンプルを投票したときの70度付近(最高点前後10度の角度成分を合成すると70.334度)
の分布は、以下のようになっています。
この数字は投票数であり、1投票は、個別の長さを持っているため、
この数字だけを平均しても、70.334度にはなりません。
data[ 65]=1
data[ 66]=3
data[ 67]=4
data[ 68]=7
data[ 69]=135
data[ 70]=2922
data[ 71]=1463
data[ 72]=35
data[ 73]=34
data[ 74]=4
data[ 75]=0
正規分布っぽい投票数になって、とてもイイ感じです。
今回は前後10度を足していますが、分散度合いは、エッジの出来、コントラストなどに依存すると思われますので、本来は、最高値位置から、対称な範囲で、最高値の1%を切った場所までなどとする必要があるように思います。
ちなみに、前後5度の合計にすると、70.333度となり、少し成績があがりました。
この時のベクトル成分はv(x,y)=(171262,479246)でした。
ピンボケがお好き?
画像処理を行う場合、一般的には、「クッキリ」とした画像を最初に得ることが必要ですが、
この処理の場合、ボカしをかけたほうが、角度精度が上がるという、ちょっと不思議(不思議でもないか)なコトが起こっています。
四角形を15度まわしたもの(垂直線は75.0度を示すハズ)と、それをボカしたものを、それぞれ角度検出してみると、
検出角度77.959度 |
検出角度75.344度 |
となって、正解の75.0度に近づくためには、3×3の画素が十分アナログ的な(デジタル的でない)情報を持っている必要があるようです。
そこで、以下のような計算を考えてみました。sobelのちょっと大きいような形です。計算量がかなり増えますが、精度に、どう影響するか、興味があります。
1 | 2 | 3 | 2 | 1 |
1 | 2 | 3 | 2 | 1 |
0 | 0 | 0 | 0 | 0 |
-1 | -2 | -3 | -2 | -1 |
-1 | -2 | -3 | -2 | -1 |
なんとなく、配列を見る限り、斜め方向に対して、上下左右方向で強いベクトルを観察するようにも見えるのですが、計算上は、これであっていると思います。 なお、ベクトルの長さは従来比で9倍になりますが、X方向Y方向とも9倍になるためベクトルの向きに影響はでません。 よって、9で割る処理は省いています。 実験結果は以下の通りです。
検出角度76.077度 |
検出角度75.294度 |
クッキリした画像のほうは改善しましたが、ボケた画像のほうは、あまり改善しませんでした。足し算回数も増えてしまうので、この変形が、よい改良なのかは微妙です。このページの上にある70.233度のものについては、まったく同じ答えを出しました。このあたりが、このアルゴリズムによる検出限界なのでしょうか。
無作為研究所トップページに戻る