############################################################## フィルタ処理について ############################################################## ========================================================= フィルタの種類 ========================================================= * 画像に乗った雑音を除去(smooth out)する. 例えば、以下のような種類がある. + 平均 ( cv2.blur, cv2.boxFilter ) + ガウシアン (cv2.GaussianBlur) + メディアン (cv2.medianBlur) + バイラテラルフィルタ (cv2.bilateralBlur) ========================================================= 畳み込みとフィルタ処理 ========================================================= --------------------------------------------------------- 連続系の畳込みについて --------------------------------------------------------- * 関数 :math:`f, g` の畳み込み :math:`f*g` は以下の式で表される. .. math:: ( f*g )(t) = \int_{-\infty} ^{\infty} f(\tau) g( t-\tau ) d\tau * ちなみに、畳み込みは、ほぼ相関関数 :math:`` のような計算. .. math:: ( f*g )(t) &= \int_{-\infty} ^{\infty} f(\tau) g( - (\tau-t ) ) d\tau \\ &= \int_{-\infty} ^{\infty} f(\tau) g^{\prime}( \tau-t ) d\tau \\ &= < f,g^{\prime} >(t) + 差分は、 :math:`g(-\tau) \rightarrow g^{\prime}(\tau)` としてあることのみ. + :math:`g(\tau)` を経時変化する感度のようなものとして捉えれば、時系列的に後に来た値に、信号 :math:`f(\tau)` の未来の情報(-方向が未来に来る情報とする)を掛け合わせるようなイメージ. + 関数gを反転する以外は、関数の相関を取る動作.偶関数となるgについては、畳込みは相関関数と同値. --------------------------------------------------------- 離散系の畳込みについて --------------------------------------------------------- * 離散系の畳込みは、連続系を離散化した以下の式で表される. .. math:: ( f*g )(x) = \sum_{i=-k}^{k} f(i) g( x-i ) --------------------------------------------------------- 離散畳込みを用いたフィルタ処理 --------------------------------------------------------- * 離散畳込みを用いて、フィルタ処理は以下のように記述できる. .. math:: (I*W)(x,y) = \dfrac{1}{S} \sum_{i=-k}^{k} \sum_{j=-k}^{k} W(-i,-j) I(x+i,y+j) * フィルタ処理した関数を Fourier 変換すると、もとの画像の波数空間上の成分と使用するフィルタのスペクトルとの積となる.つまり、低波数の情報を落としたければ、低波数が落ちるようなフィルタを、高波数が落としたければ、高波数で低減されているスペクトルを持つ関数をフィルタ関数に選べば良い. ========================================================= 単純平均フィルタの例 ========================================================= * 単純平均フィルタは、 cv2.blur 及び、cv2.boxFilter と 関数が2つある. + boxFilterは ビット深度(depth)と非正規化フィルタ ( normalize=False ) でのフィルタリングが可能. * 単純平均フィルタは、単純平均をとるような行列(フィルタカーネル)を用いて、入力画像の部分行列に対してスライディングウィンドウ方式で作用させ、内積を取る. + 例えば、3x3の単純平均フィルタは、 .. math:: F_{avg} = \dfrac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix} * 指定項目が少なく、扱いやすい **"cv2.blur"** を使えばよい. :: img_out = cv2.blur( img_in, kernel_size ) * ( e.g. ) :: img_out = cv2.blur( img_in, (5,5) ) .. image:: ../image/lena_blur.jpg :width: 300px :align: center ========================================================= ガウシアンフィルタの例 ========================================================= * ガウシアンフィルタは、各画素間の距離に応じてガウス関数的に変化する関数を用いて重み付け局所平均をとる画像フィルタ. * 関数は以下である.(参考URL:"https://algorithm.joho.info/image-processing/gaussian-filter/") .. math:: g(x,y,\sigma) = \dfrac{1}{ \sqrt{2 \pi} \sigma } \exp \left[ - \dfrac{x^2+y^2}{ 2 \sigma^2 } \right] * 標準偏差 σ は、ガウシアンフィルタの拡がり. + σ:大 で、単純平均フィルタに近い、ぼやけたフィルタに(強いフィルタ). + σ:小 で、局所での変化を反映できる急峻な変化を捉えるシャープなフィルタに(弱いフィルタ). * フィルタカーネルは、 カーネルサイズ 3x3、 :math:`\sigma=1.3` において、例えば、 .. math:: F_{Gauss} = \dfrac{1}{16} \begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix} * ガウシアンフィルタの適用. :: img_out = cv2.GaussianBlur( img_in, kernel_size, sigma ) + kernel_size は整数のタプルで与える + sigmaは、上記ガウス関数の標準偏差を与えるパラメータ.0として与えた場合、自動的に決定される. - 参考URL 1. GaussianBlur項 ("https://docs.opencv.org/3.4/d4/d86/group__imgproc__filter.html#gaabe8c836e97159a9193fb0b11ac52cf1") - 参考URL 2. getGaussKernel項 ("https://docs.opencv.org/3.4/d4/d86/group__imgproc__filter.html#gac05a120c1ae92a6060dd0db190a61afa") - 記載のkernel_sizeからの sigma の計算式は .. math:: \sigma = 0.3*( (ksize-1)*0.5 - 1 ) + 0.8 - ksize=3 において、sigma=0.8, ksize=5 において sigma=1.1 * ( e.g. ) :: img_out = cv2.GaussianBlur( img_in, (5,5), 0 ) .. image:: ../image/lena_gauss.jpg :width: 300px :align: center ========================================================= Sobelフィルタの例 ========================================================= * 高波数成分を残すハイパスフィルタでよく使用されるSobelフィルタについて、以下に例を記す. .. math:: F_{Sobel}^{x} = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}, \ \ \ \ \ \ F_{Sobel}^{y} = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix} * Sobelフィルタは、微分フィルタに平均化を組み合わせたフィルタである. + 本来ノイズに弱い微分フィルタを、微分と直行する方向で平均化することにより安定した微分を可能とする. + 勿論、微分値をスムージングするのと同値. .. math:: F_{Sobel}^{x} = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix} = \begin{bmatrix} 1 \\ 2 \\ 1 \end{bmatrix} \begin{bmatrix} -1 & 0 & 1 \end{bmatrix}