前回は距離変換でした。まあ距離はなんだかんだ言って分かり易いっす。今回はHough変換です。「ハフ」と発音すればよいみたいです。画像内の直線、あるいは円を検出するための「変換」のようです。Scilab IPCVにも直線用と円用の2つの関数が存在する雰囲気ではあるのだけれど。円用は?なので今回は直線だけ。
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※Windows11上の Scilab2024.0.0およびScilab上のScilab IPCVツールボックスを使用させていただいております。
Hough Transformation
画像内の直線などの図形の検出を「図形パラメータ空間」内での投票に置き換えることで行う変換なのだそうな、ハフ変換。ハフ様の御発明。素人老人がブツクサ言ってもせん無いので、『CVMLエキスパートガイド』様の以下のページなどご参照くだされ。
ハフ変換 (Hough Transform) による直線・円の検出
Scilab IPCVには、以下の2関数が含まれている「みたい」です。
-
- imhough
- imhoughc
お名前からして、imhoughcの方が「円の検出用」に思われるのですが、helpページも不在なのでよくわからんです。ということで今回は「直線の検出用」らしいimhoughの方だけ手習ひしてみます。書式は以下に。
[HM, rho, th] = imhough(S)
-
- rho 原点からの距離
- th 原点からの角度
- HM Hough Matrix、ぶっちゃけ投票結果の数字?
ここで原点は図形の左上隅ってことで良さそう?なのですが、距離と角度についての単位は不明。多分、距離は入力画像の画像のピクセルサイズによるみたい(単位ピクセル数ってことかい。でも距離がマイナスになるのはどゆこと?)また、角度は右肩上がりで正の値、右肩下がり?で負の値に見えるような感じっす。
とりあえず実データに適用
訳もわからず実データに適用してみた例が以下に。上記参考文献などでは、リアルな世界の画像に対して輪郭線抽出など前処理を行った上で、ハフ変換かけているのですが、今回の例は手書きの白黒図形(データとしてはPNG形式だけども)です。サンプルデータの中に2直線の図があったので、それを真似して1直線と3直線の図を追加で作製して処理してみました。
Sh = imread("h1Line.png"); [HMh, rhoh, thh] = imhough(Sh); Sv = imread("vLine.png"); [HMv, rhov, thv] = imhough(Sv); S2 = imread(fullpath(getIPCVpath() + "/images/2lines.png")); [HM2, rho2, th2] = imhough(S2); S3 = imread("3Lines.png"); [HM3, rho3, th3] = imhough(S3); scf(); subplot(241); title('hLine'); imshow(Sh); subplot(242); title('vLine'); imshow(Sv); subplot(243); title('2Lines'); imshow(S2); subplot(244); title('3Lines'); imshow(S3); subplot(245); Sgrayplot(thh,rhoh,HMh',strf="021"); subplot(246); Sgrayplot(thv,rhov,HMv',strf="021"); subplot(247); Sgrayplot(th2,rho2,HM2',strf="021"); subplot(248); Sgrayplot(th3,rho3,HM3',strf="021");
処理した結果が以下に。
上記の上の段が元の図形です。下がHough変換後の値を「カラフル」にプロットしたもの。x軸が角度で、y軸が距離です。色が強調されている(赤色の内側)ところが投票のピークだと思います。
確かに3本線は3つのピーク、2本線は2つのピークが見えとります。しかし図形パラメータ空間、なかなかなもんじゃの~。どうするの。