勾配ベースのハフ変換を実装する方法


9

私はエッジ検出にハフ変換を使用しようとしています、そして基礎として勾配画像を使用したいと思います。

私はこれまでやっていること、画像所与のIサイズの[M,N]とその偏導関数gxgy、各画素の勾配角度を計算することですthetas = atan(gy(x,y) ./ gx。同様に、勾配の大きさをとして計算しmagnitudes = sqrt(gx.^2+gy.^2)ます。

ハフ変換を作成するには、次のMATLABコードを使用します。

max_rho = ceil(sqrt(M^2 + N^2));
hough = zeros(2*max_rho, 101);
for x=1:M
    for y=1:N
        theta = thetas(x,y);
        rho = x*cos(theta) + y*sin(theta);

        rho_idx = round(rho)+max_rho;
        theta_idx = floor((theta + pi/2) / pi * 100) + 1;
        hough(rho_idx, theta_idx) = hough(rho_idx, theta_idx) + magnitudes(x,y);
    end
end

結果のハフ変換はもっともらしいようですが(http://i.stack.imgur.com/hC9mP.pngを参照)、元の画像のエッジパラメーターとして最大値を使用しようとすると、結果はだいたいランダムに見えます。ハフ変換の構築で何か問題がありましたか?

更新:私のコードで愚かな間違いがありました:ではなくrhoとして計算されx*cos(theta)+y*cos(theta)ましたx*cos(theta)+y*sin(theta)。つまり、コサインとサインの代わりに2つのコサインを使用していました。上記のコードを編集し、新しい結果の画像を以下に示します。しかし、これははるかに良いエッジを与えませんでした。

@endolith:の最大値を考慮すると、エッジをプロットするhough-マトリックスでrho_idx, theta_idx私はインデックスを翻訳し、rho,theta値:

theta = (theta_idx -1) / 100 * pi - pi / 2;
rho = rho_idx - max_rho;

最後に、エッジをとしてプロットしますy= (rho - x*cos(theta)) / sin(theta)

新しい結果


「元の画像のエッジパラメータとして最大値を使用しようとしたとき」どのようにしていますか?
エンドリス'27

@Jonas Due Vesterhedenこれは時間対ドップラー周波数画像ですか?...
Spacey

@Mohammad:私が知っていることではありません。元の画像は一部の回路基板です。「VS」とはどういう意味ですか?
Jonas Due Vesterheden、2011年

@JonasDueVesterheden「VS」は単に「対」を意味します。(時間対ドップラー周波数 '):-)
スペイシー

非最大抑制を適用する前に、ハフマップをスムーズにする必要があります。

回答:


2

私はあなたの質問に少し混乱しています。エッジではなく、ラインを検出するためにハフ変換が使用されます。

必要なのがエッジマップだけである場合は、勾配の大きさをしきい値処理するか、Cannyエッジ検出器などのより豪華なものを使用する必要があります。

直線を検出したい場合は、エッジマップから始めてhough、画像処理ツールボックスにアクセスできる場合は、関数を使用することをお勧めします。グラデーションでハフ変換を実行する際の問題は、直線を形成するエッジピクセルのグラデーションの向きが逆になる可能性があることです。たとえば、市松模様を考えてみましょう。2列の正方形の間のエッジは、上に黒い四角があり、下に白い四角があるか、またはその逆かによって、向きが反転します。

あなたの実装に関しては、ハフ行列のビンが小さすぎることが問題だと思います。基本的に、rho次元のビンサイズは1で、theta次元のビンサイズは2度未満です。つまり、実際にはめったに発生しないラインを形成するために、グラデーションの向きが非常に正確に降りなければなりません。ビンが大きくなるようにrho_idxとtheta_idxを計算すると、ライン検出器のエラー耐性が向上し、より良いラインが得られる可能性があります。


1

これが問題であるかどうかはわかりませんが、象限があいまいであるため、atan()では-90から+90度の角度しか得られません。完全な勾配角度(-180から180)を取得するには、atan2()を使用する必要があります。


提案をありがとう!私が理解しているように、エッジの「方向」は重要ではないため、-90〜+90度の角度を使用するだけで十分です。を使ってみましたatan2が、問題が解決していないようです。
Jonas Due Vesterheden、2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.