所謂不変じゃないハフ変換であれば、回転やリサイズに対応していません。しかし、不変ハフ変換はこれらを対応してくれます。ハフ法は基本的にパターンのマッチングです。例えば右の図にある黒い線でできた形状を絵から探したい。そうなりますと、三つの要素を確定させる必要があります。 1. 位置 2. 回転角度 3. サイズ 最重要となる部分は位置です。図形は回転されているや拡大縮小されているかもしれないので、これに強い解析法が必要になります。一つの方法としては、図に示されたように、角度を利用します。 仮にエッジポイント\( \omega_1 \)を発見しました。\( \omega_1 \)はパターンのどの辺にあるかを知りたい。\( \omega_1 \)とその勾配であれば、パターンのどこでもあるかもしれませんので、検索範囲は大きい過ぎます。このため、\( \omega_1 \)とその勾配から固定の\( \alpha \)を足した方向でエッジポイントを探します。仮に\( \omega_2 \)に到達したとします。\( \omega_2 \)も勾配がありますから。\( \omega_1 \)と\( \omega_2 \)の切線は角\( \beta \)を形成します。この\( \beta \)は回転とサイズに無関係です。\( \omega_1 \)とその\( \beta \)はともになって、位置検索の手がかりになります。\( ( \omega_1, \beta ) \)ではパターンの方向が分かります。\( \omega_1 \)から一定の角度\( k \)に沿って直線を描けば、図形の中心位置を通すことができます。描きながら投票すれば、図形の中心位置は決まります。図形の中心位置は予め設定できます。決まりはないですが、\( \beta \)の値を有効に使うため、図形の中心位置は図形の中に置いた方がいいでしょう。例えばパターンの全座標の平均値に置くなどです。\( k \)はパターンから予め計算できます。\( \beta \)の区間をテーブルに詰め込んで、可能な\(… Read more »
偶然のように見えてしまう必然、数学は証明してくれます。私は勉強している所、楕円の四点が一本の直線にあると、半信半疑でした。しかし、実際に演算してみると、全く偶然ではなかった。 楕円は下記のような式で表現できます。 \[ \left[ \begin{array}{c} x(\theta) \\ y(\theta) \end{array} \right] = \left[ \begin{array}{c} x_0 \\ y_0 \end{array} \right] + \left[ \begin{array}{c} a \times cos(\theta) \\ b \times sin(\theta) \end{array} \right] \] 右の図に示された楕円に、\( (x_0,y_0) \) と \( (x_m,y_m) \) と \( (x_\theta,y_\theta) \) と \( (x_T,y_T) \) が一本の直線にあります。\( (x_1,y_1) \)と\( (x_2,y_2) \)は楕円上の2点です。\(… Read more »
画像の中の物体が移動すると、一定の方向に沿って移動します。この方向と距離を示すベクトルはいわゆるオプティカルフロー(Optical Flow)です。この方向の検出は大変複雑の過程であり、これを簡単化するために、二つの前提条件が設けられました。一つは、移動前と移動後、移動された点の明るさは変わらないことです。一つは、近い点のグループはほぼ同一な移動をします。 \( P(t)_{x,y} \)を時点\(t\)の画像\(P\)の、\((x,y)\)座標にある点の明るさとします。分析のため、\(P\)を可微分に考えます。そうすると、\( P \)は\( \mathbb{R}^3 \to \mathbb{R} \)の関数になります。テイラー式で\(P\)を展開してみます。 (式1): \[ P(t+\delta t)_{x+\delta x,y+\delta y}=P(t)_{x,y} + \delta x \frac{\partial P}{\partial x}+\delta y \frac{\partial P}{\partial y} + \delta t \frac{\partial P}{\partial t} + \zeta \] このうち、\( \zeta \)は高次剰余なので、引数の変化が小さい場合のみを考慮しますので、\( \zeta \)を無視します。ここで、一つ目の前提仮設を使います。つまり:\( P(t+\delta t)_{x+\delta x,y+\delta y}=P(t)_{x,y} \)、これを(式1)に代入しますと、 \( 0=\delta x \frac{\partial P}{\partial x}+\delta… Read more »
画像を解析する場合において差分法は良くしようされます。差分法は簡単ですが、ノイズに影響され易いです。結局に要るか要らないか、沢山の特徴候補が出てきます。これを軽減するため、ガウススムージングはよく使用されます。しかし、単なるガウススムージングでは、ノイズの軽減には有効ですが、あまり消せません。いわば、更なる一層のスムージングが必要になります。 Scale Spaceは実際に一種のスムージングとして考えられます。一枚の画像のサイズを段々に小さくして行きます。大きい画像は下の層に置かれ、小さい画像は上の層に置かれるように考えますと、ピラミッドのような構想ができます。このピラミッドはスケールスペース(Scale Space)と言われます。それぞれの層にそれぞれの候補特徴があります。特定の特徴がもし主要特徴であれば、複数の層に渡って、この特徴が保持されると考えられます。これがポイントです。ノイズでできた候補特徴は層と層の間のチェックで段々消されます。最後に残る物として、有望な候補特徴のみです。 多くの層を作るので、時間掛かると思われますが、そんなに掛からないかもしれません。層毎に画像が小さくなりますので、\( n \)層目のサイズは\( \frac{2}{1.5^n} \)に比例します。つまり、ピラミッドの上に行けば、画像のサイズは急激に小さくなります。また、最初の処理に沢山の候補特徴が出てきますが、次の画像層に素早く落とされます。ピラミッドの毎層にも候補特徴が追加されますが、大した数にはなりません。 私の実験に、512×512の画像を使用しました。0.43秒で結果が出ます。最初の層に17867個の候補特徴が検出されますが、5階層を経て539個に収まります。ただし、実際に実験してみれば分かりますが、やはりチューニングが必要です。パラメータによって、画像別に効果がかなり違う場合があります。また実験しながら、いくつかの注意点があることを気づきました。 注意点1:画像補間とスムージングのステップにかなり注意が必要です。階層間の画像の内容の相対位置がずれないように確保しなければなりません。そうでなければ、下位階層の画像内容が上位階層に確認できなくなります。 注意点2:終了までの特徴候補数は何らかの制限が必要です。そうでなければ、殆どは淘汰されます。原因は簡単です。ピラミッドは段々に一点に集中します。情報量が小さくなり、全画像が少ない数点にブレンドします。最中的に特徴候補に値しない点が対応しているすべての候補特徴は淘汰されます。最後の一点にカバーされる候補特徴のみが残ります。
角は画像の中の一種の基礎特徴とも言えます。 もっとも基本的な方法としてはエッジの角度を算出し、近隣のエッジポイントの角度の差を計算します。これは基本的に差分法になりますので、ノイズにとても影響され易いと考えられます。このため、この基本方法から一歩か二歩を進んだ方法にHarris法があります。 Harris法は\( (x,y) \)を中心とする、\( (x+i,y+j) \)のウィンドウを考えます。\( ( (i,j) \in [-w,w]\times[-w,w] ) \) このウィンドウにバイアスを加えて\( (x+i+u,y+j+v) \)と\( (x+i,y+j) \)の差を考えます。もし\( (u,v) \)はエッジの方向にそっているなら、差は小さいはずです。エッジに沿わないなら、差は大きいはずです。Harris法はエッジポイントにおいて、差の合計が最小になるように\( (u,v) \)を探し、最小の合計値を曲率の指標とします。つまり、下記の式になります。 \[ E_{u,v}=\sum_{i=-w}^{w}\sum_{j=-w}^{w}(\frac{\partial P_{x+i,y+j}}{\partial x}u+\frac{\partial P_{x+i,y+j}}{\partial y}v)^2 \] Harris法は\( \{ (u,v) | \| (u,v) \|=1 \} \)において、最小の\( E_{u,v} \)を探します。 一見、単位円に沿って\( (u,v) \)を試していく必要があるようですが、実際はそうではありません。数学は美しく助けてくれます。まずは、詳しく見ましょう。\( E_{u,v} \)は下記の式に分解できます。 \[ E_{u,v}=A(x,y)^2 u^2 + 2… Read more »
もう一つの二次差分エッジ検出法はMarr-Hildreth法です。 これはガウススムージングから由来します。マグニチュードを無視すれば、二元ガウス関数は下記の形式を取ります。 \( g(x,y;\sigma)=e^{-\frac{x^2+y^2}{2\sigma^2}} \) \( g(x,y;\sigma) \)の微分を二回計算すれば下記のような式になります。 \( \triangledown^2g(x,y;\sigma)=\frac{1}{\sigma^2}{\left( \frac{(x^2+y^2)}{\sigma^2}-2 \right)}e^{-\frac{x^2+y^2}{2\sigma^2}} \) この式の\( x \)と\( x \)に座標を割り当てるとMarr-Hildreth法のテンプレートが出来上がります。ただし、注意点があります。このテンプレートは修正が必要です。原因はこのテンプレートの合計はゼロではないからです。ゼロでないと、各座標において算出された二次差分は全体的に正数か負数に偏ることが発生します。結局ゼロ交差でのエッジの検出はできなくなります。これ点を注意した上で結果を見てみましょう。 画像が大きいため、この処理結果を得るには120秒掛かりました。
一次差分法でエッジを検出する方法はありますが、さらに考えますと、一次差分が最大値に至ったときにエッジが記録されます。一次差分が最大値に達する点は、二次差分の符号が変わる時でもあります。なので、二次差分の符号が変わる点を割り出せば、エッジが分かるはずです。 この中、もっとも簡単なものかも知れませんが、ラプラシアン法があります。ラプラシアン法は下記のようなテンプレートを使用します。 \( \left[ \begin{array}{rrr} 0 & -1 & 0 \\ -1 & 4 & -1 \\ 0 & -1 & 0 \end{array} \right] \) このテンプレートの出力結果は図1にあります。 結構酷いですね。じゃあ、もうちょっと平均してみましょうか、なので、下記のような周辺8点を全部入れましょう。 \( \left[ \begin{array}{rrr} -1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1 \end{array} \right] \)… Read more »
Cannyエッジ検出法は一般に四つのステップがあります。 ガウススムージング Sobel法によるエッジ検出 非最大値抑制 ヒステリシス閾値化 Sobel法では、ある程度のスムージングが効いています。ただ、その標準偏差は変えられない。Sobel法の前に別途スムージングのステップを組めば、より良いノイズ耐性は期待できます。 Sobel法では、一個の画素に対して、横と縦二回の検査があります。横と縦に方向での明暗変化の強さが求められ、エッジの方向は分かるようになります。仮に、横と縦の変化量を\( Mx \)と\( My \)とすれば、エッジの方向は下記の式で算出されます。 \(\theta=tan^{-1}\left( \frac{My}{Mx} \right)\) もちろん、\( Mx \)と\( My \)の符号を考慮に入れれば、\( [0,2\pi) \) の角度は求められます。この角度を非最大値抑制のステップで活用します。 非最大値抑制の目的は、検出されたエッジを細くするためです。明暗変化は上げ下げしているので、綿花のもっとも激しいところをエッジにし、そのたの画素をエッジにしないことが目的です。 画像の画素は離散しているため、一つの画素の周辺は八個の画素しかありません。しかし、エッジの方向は非常に多いです。現在対象の画素は最大であるかどうかをより正確に検出するため、Canny法は数値補間を使用します。イメージとしては図1をご覧ください。 図1に大きい丸は実在する画素を意味します。\( M(\cdot,\cdot) \)は画素の明るさです。\( M1\)と\( M2\)は補間によって算出される非実在の画素の明るさです。図1の実線の直線はエッジで、点線はエッジを跨ぐノーマル方向です。画素がノーマル方向において、最大である場合に限ってエッジにいると認定されます。この様な画素だけが保留され、そうでない点は全部消されます。 ステップ3直後の効果をまずは見てみましょう。 図2を詳しく見てみますと、薄い灰色の顔の輪郭は見られます。また、人の目ではなかなか見えないですが、図2に黒に使い画素は多々あります。見せるためだけ、これらの点を全部明るくしたバージョンは図3です。 黒に近い点は所謂ノイズで形成されています。エッジから除外されるべきです。これはステップ4、ヒステリシス、の役割です。ヒステリシスとは延滞です。エッジに充分なり得る一点から初め、周辺に探って行きます。エッジになり得ない点を除き、すべての点はエッジにする。結果は驚きほどです。図4です。 輪郭だけが残りました。顔の主要特徴は残されています。 Canny法の欠点はスピードにあります。ステップ1とステップ2はかなり時間を食います。もちろんテンプレートサイズを小さくされば時間短縮になります。効果は少し落ちますが、まあ~、そんなに悪くない。
パスカル三角形は数学上で大変有名です。三角形は内容は一階層ごとに二項式の係数になっています。下の層の係数は上の層の2個の近隣係数の合計です。例えば下のようなものです。
|
1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 |
この例はいわば合計のパスカル三角形です。差分のパスカル三角形もあります。一層目は1と-1になるだけです。計算ルールは同じです。例えば下の物です。
|
1 -1 1 0 -1 1 1 -1 -1 1 2 0 -2 -1 1 3 2 -2 -3 -1 1 4 5 0 -5 -4 -1 |
詳しく見てみれば、左右から中間へ合計のパスカル三角形の近隣二項の差を取れば、ぴったりと差分のパスカル三角形になります。 パスカル三角形の内容は二項式計数なので、基本的に下記の有名な式で計算できます。 $$ \left( \begin{array}{c} n \\ k \end{array} \right) =\frac{n!}{(n-k)!k!} =\frac{n(n-1)(n-2) \ldots (n-k+1)}{k!} $$ この計算法の問題点としては、分子と分母ともに2個の大きい数字ができてから割り算をします。結果はオーバーフローはより起こりやすいです。このため、パスカル三角形のような足し算だけで計算したほうが穏便です。もう一点では、一般に掛け算が足し算より遅いです。同様な計算回数であれば、一般に足し算の方が早く終わります。これはコンピュータも人間も同じのようです。 指定サイズ(SIZE)のパスカル三角形の最後の層は下記のようなコードで計算できます。
|
P[0]=1; P[1]=1; // 1を-1にすれば、差分のパスカル三角形になります。 for (y=2;y<SIZE;y++) { b=0; for (r=y;r>0;r--) { P[r]=P[r-1]+b; b=P[r-1]; } } |
画像処理の試み 一次差分法でエッジ検出にもっとも基本的なエッジ検出方として一次差分法を紹介しました。右の図に示されたように、素描のような影が出て悪くない感じですね。用途によっては、これ結果は良いでしょう。でも、エッジ検出の観点から見れば、この結果はあまりいいとは言えません。頬と額のエリアに注目してみましょう。頬と額はかなり黒塗りされています。その黒さは全部エッジの誤認です。誤認の原因は、原始画像は一見滑らかに色が変化しているように見えても、実際に局部の画像を拡大して見れば、多くのでこぼこは見れます。一次差分法はこのでこぼこを明暗の差として認識し、エッジとしました。一次差分が頻繁の名鑑変化を広いスケールで見れず、画素の組み合わせは安易に明暗変化として認識してしまう。この性質は人間の目と大きい違いがあります。この問題を解消した炒め、よく使用される方法は、エッジ検出の前に何らかの方法でスムージングをかけます。 一次差分の問題点を具体的に見てみましょう。 \(y_1(n)=x(n)-x(n-1)\) (1) \(y_2(n)=x(n)-x(n-2)\) (2) (1)はもっとも基本的な一次差分です。図1からは高周波では反応が強いです。これがあのでこぼこの原因です。(2)はよくある改善法として、高周波数においては、応答は落ちます。これによって所謂高周波ノイズの影響は小さくなります。Sobel法は(2)を使用しています。でもこれだけではありません。 画像は縦と横の二方向あります。一方向で差分を検出している時に、もう一方向のデータにあまり影響されては困る。このため、Sobel法は一方で差分をしている同時に、もう一方ではスムージングを行います。スムージングの方法はガウススムージングの整数バージョンです。つまり、二項式の係数を使用します。このやり方は不思議かも知れませんが、実際に数字のスケールだけが番って、値間の倍数で考えればまったく同じく見えます。実例で見ましょう。 図2に、緑と赤の2本の曲線があります。ほぼ完全に重なっていますね。赤い方はガウスで緑の方は二項式係数です。二項式係数使用しますと、複雑な指数関数を使用しなくともガウス同等な効果を得られます。ただ一点だけを注意する必要があります。二項式が長すぎると係数が大き過ぎになり、オーバーフローが発生します。ある基準によると、ガウスは最良な画像スムージング法とも言われます。周波数応答は下の図3に記されます。 この周波数応答の形状はまさにガウスその物です。はっきりとローパスフィルターが映っています。 縦方向のエッジを検出するためのSobelテンプレート下記のような行列です。横方向のエッジを検出するためのSobelテンプレートは縦方向の転置です。 \( \left[ \begin{array}{rrrrrrrrr} {1} & {6} & {14} & {14} & {0} & {-14} & {-14} & {-6} & {-1}\\ {8} & {48} & {112} & {112} & {0} & {-112} & {-112} & {-48} & {-8}\\ {28} &… Read more »