画像フィルタリング =========================== .. highlight:: c このセクションで述べる関数およびクラスを利用して, 2次元画像に対する,様々な線形・非線形のフィルタリング処理を行います.このフィルタリング処理では,入力画像の各ピクセル位置 :math:`(x,y)` の近傍領域(通常は矩形)を利用して出力値を求めます.この出力は,線形フィルタの場合はピクセル値の重み付き和,モルフォロジー演算の場合は,最大値・最小値となります.求められた出力は,出力画像上の同じ位置 :math:`(x,y))` に保存されます.これはつまり,出力画像が入力画像と同じサイズになることを意味します.また通常,関数はマルチチャンネル配列をサポートしており,各チャンネルが個別に処理されるので,出力画像のチャンネル数も入力画像と同じ数になります. このセクションで述べる関数とクラスに共通するもう1つの特徴は,これらは単純な算術関数とは異なり,存在しないピクセルの値を外挿する必要があるということです.例えば, :math:`3 \times 3` のガウシアンフィルタを用いて画像の平滑化を行いたい場合,各行の左端のピクセルを処理する際に,さらにその左側,つまり,画像外のピクセルが必要となります.このようなピクセルを,画像の左端のピクセルと同じものだと仮定する(つまり,「複製境界」外挿法),あるいは,存在しないすべてのピクセルを 0 とする(つまり,「定数境界」外挿法)などの処理が可能です. .. index:: IplConvKernel .. _IplConvKernel: IplConvKernel ------------- `id=0.178735411881 Comments from the Wiki `__ .. ctype:: IplConvKernel IplConvKernel は, :ref:`CreateStructuringElementEx` によって作成される,矩形の畳み込みカーネルです. .. index:: CopyMakeBorder .. _CopyMakeBorder: CopyMakeBorder -------------- `id=0.691814601944 Comments from the Wiki `__ .. cfunction:: void cvCopyMakeBorder( const CvArr* src, CvArr* dst, CvPoint offset, int bordertype, CvScalar value=cvScalarAll(0) ) 画像をコピーし,その周りに境界を作成します. :param src: 入力画像. :param dst: 出力画像. :param offset: 入力画像(あるいは,そのROI)のコピー先となる出力矩形領域の,左上のコーナー座標(画像の原点が左下の場合は,左下コーナーの座標).この矩形領域のサイズは,入力画像サイズ/ROIサイズと一致します. :param bordertype: コピーされた入力画像の周りに作成される境界領域の種類.以下のいずれか(IPLでサポートされていた別の2種類の境界, ``IPL_BORDER_REFLECT`` および ``IPL_BORDER_WRAP`` は,現在はサポートされていません): * **IPL_BORDER_CONSTANT** 境界領域は,この関数の最後の引数として渡された定数で埋められます. * **IPL_BORDER_REPLICATE** 境界領域は,画像の上下の1行,左右の1列の画素値が複製されたもので埋められます. :param value: ``bordertype`` が ``IPL_BORDER_CONSTANT`` である場合の,境界領域の値. この関数は,2次元の入力配列を出力配列の内側にコピーし,その周りに指定された種類の境界領域を作成します.この関数は,特定のアルゴリズム内部で利用される境界領域とは別のものをエミュレートする必要がある場合に役立ちます.例えば,モルフォロジー演算の関数は,OpenCV の多くのフィルタリング関数と同様に内部では複製境界を使用していますが,ユーザにとって境界が不要だったり,あるいは 1 や 255 の値で埋められた境界が必要な場合もあるかもしれません. .. index:: CreateStructuringElementEx .. _CreateStructuringElementEx: CreateStructuringElementEx -------------------------- `id=0.230731327516 Comments from the Wiki `__ .. cfunction:: IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchorX, int anchorY, int shape, int* values=NULL ) 構造要素を作成します. :param cols: 構造要素の列数. :param rows: 構造要素の行数. :param anchorX: アンカーポイントの水平方向の相対オフセット値. :param anchorY: アンカーポイントの垂直方向の相対オフセット値. :param shape: 構造要素の形状.以下のような値をとります: * **CV_SHAPE_RECT** 矩形の構造要素. * **CV_SHAPE_CROSS** 十字の構造要素. * **CV_SHAPE_ELLIPSE** 楕円の構造要素. * **CV_SHAPE_CUSTOM** ユーザー定義形状の構造要素.この場合,パラメータ ``values`` がマスク(つまり,構成要素の点と見なされるピクセルの周辺領域)を指定します. :param values: 平面配列である構造要素データへのポインタであり,構造要素行列を行毎に走査したものを表しています.データが0以外の値の場合は構造要素を構成する点であることを示します.このポインタが ``NULL`` の場合は,すべての値が0ではないとみなされ,構造要素は矩形形状となります.なお,このパラメータは,shape が ``CV_SHAPE_CUSTOM`` の場合にのみ有効です. この関数は,モルフォロジー演算の構造要素として利用する構造体 ``IplConvKernel`` の領域を確保し,それを初期化します. .. index:: Dilate .. _Dilate: Dilate ------ `id=0.77503490494 Comments from the Wiki `__ .. cfunction:: void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 ) 指定された構造要素を用いて画像の膨張を行います. :param src: 入力画像. :param dst: 出力画像. :param element: 膨張に用いる構造要素.これが ``NULL`` , の場合, :math:`3\times 3` の矩形形状の構造要素が用いられます. :param iterations: 膨張が適用される回数. この関数は,ピクセル近傍領域の形状を決定する任意の構造要素を用いて,画像を膨張させます.以下のように,対象ピクセルの近傍領域の最大値をそのピクセル値とします: .. math:: \max _{(x',y') \, in \, \texttt{element} }src(x+x',y+y') この関数は,置換モードをサポートします.膨張は,複数回( ``iterations`` )繰り返し適用することができます.カラー画像の場合,各チャンネルは独立に処理されます. .. index:: Erode .. _Erode: Erode ----- `id=0.933405301994 Comments from the Wiki `__ .. cfunction:: void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1) 指定された構造要素を用いて画像の収縮を行います. :param src: 入力画像. :param dst: 出力画像. :param element: 収縮に用いる構造要素.これが ``NULL`` , の場合, :math:`3\times 3` の矩形形状の構造要素が用いられます. :param iterations: 収縮が適用される回数. この関数は,ピクセル近傍領域の形状を決定する任意の構造要素を用いて,画像を収縮させます.以下のように,対象ピクセルの近傍領域の最小値をそのピクセル値とします: .. math:: \min _{(x',y') \, in \, \texttt{element} }src(x+x',y+y') この関数は,置換モードをサポートします.収縮は,複数回( ``iterations`` )繰り返し適用することができます.カラー画像の場合,各チャンネルは独立に処理されます. .. index:: Filter2D .. _Filter2D: Filter2D -------- `id=0.121661849052 Comments from the Wiki `__ .. cfunction:: void cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1,-1)) 指定されたカーネルで,画像の畳み込みを行います. :param src: 入力画像. :param dst: 出力画像. :param kernel: 畳み込みカーネル.シングルチャンネル,浮動小数点型の行列.異なるチャンネルに異なるカーネルを適用したい場合は, :ref:`Split` を用いて画像を色平面に分解し,それぞれを個別に処理します. :param anchor: フィルタ対象となる点のカーネル内での相対位置を示す,カーネルのアンカー.アンカーはカーネル内に存在します.デフォルト値である (-1,-1) は,カーネル中心を表す特別な値です. この関数は,画像に任意の線形フィルタを適用します.また,置換モードでの処理がサポートされます.フィルタ範囲が部分的に画像外に出てしまった場合,この関数は,画像内にある最近傍のピクセルから範囲外のピクセル値を補間します. .. index:: Laplace .. _Laplace: Laplace ------- `id=0.76695215109 Comments from the Wiki `__ .. cfunction:: void cvLaplace( const CvArr* src, CvArr* dst, int apertureSize=3) 画像のラプラシアンを求めます. :param src: 入力画像. :param dst: 出力画像. :param apertureSize: アパーチャサイズ( :ref:`Sobel` の場合と同じ). この関数は,以下のように Sobel オペレータを使って計算されたxとyの2次微分を足し合わせることで,入力画像のラプラシアンを求めます: .. math:: \texttt{dst} (x,y) = \frac{d^2 \texttt{src}}{dx^2} + \frac{d^2 \texttt{src}}{dy^2} ``apertureSize`` = 1 を指定すると,画像と以下のカーネルの畳み込み処理と同じ処理を,最も高速に計算できます: .. math:: \vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0} 関数 :ref:`Sobel` と同様にスケーリングは行われなず,サポートする入出力画像のフォーマットも同じです. .. index:: MorphologyEx .. _MorphologyEx: MorphologyEx ------------ `id=0.633639604358 Comments from the Wiki `__ .. cfunction:: void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation, int iterations=1 ) 高度なモルフォロジー変換を行います. :param src: 入力画像. :param dst: 出力画像. :param temp: いくつかの場合で必要とされる,テンポラリな画像. :param element: 構造要素. :param operation: モルフォロジー演算の種類,以下のいずれか: * **CV_MOP_OPEN** オープニング. * **CV_MOP_CLOSE** クロージング. * **CV_MOP_GRADIENT** モルフォロジー勾配. * **CV_MOP_TOPHAT** トップハット変換. * **CV_MOP_BLACKHAT** ブラックハット変換. :param iterations: 収縮および膨張の適用回数. この関数は,収縮および膨張を組み合わせた高度なモルフォロジー変換を行うことができます. オープニング: .. math:: dst=open(src,element)=dilate(erode(src,element),element) クロージング: .. math:: dst=close(src,element)=erode(dilate(src,element),element) モルフォロジー勾配: .. math:: dst=morph \_ grad(src,element)=dilate(src,element)-erode(src,element) トップハット変換: .. math:: dst=tophat(src,element)=src-open(src,element) ブラックハット変換: .. math:: dst=blackhat(src,element)=close(src,element)-src モルフォロジー勾配,およびトップハット変換とブラックハット変換の置換モードでは,テンポラリな画像 ``temp`` が必要です. .. index:: PyrDown .. _PyrDown: PyrDown ------- `id=0.440887806417 Comments from the Wiki `__ .. cfunction:: void cvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 ) 画像のダウンサンプリングを行います. :param src: 入力画像. :param dst: 出力画像.幅と高さは,入力画像の半分になります. :param filter: 畳み込みフィルタの種類.現在は, ``CV_GAUSSIAN_5x5`` だけがサポートされています. この関数は,ガウシアンピラミッド分解の1ステップであるダウンサンプリングを行います.まず,入力画像と指定されたフィルタの畳み込みを行い,画像の偶数行と偶数列を間引くことでダウンサンプリングを行います. .. index:: ReleaseStructuringElement .. _ReleaseStructuringElement: ReleaseStructuringElement ------------------------- `id=0.246677386627 Comments from the Wiki `__ .. cfunction:: void cvReleaseStructuringElement( IplConvKernel** element ) 構造要素を削除します. :param element: 削除される構造要素へのポインタ. この関数は,不要になった構造体 ``IplConvKernel`` を解放します. ``*element`` が ``NULL`` の場合は,この関数は何もしません. .. index:: Smooth .. _Smooth: Smooth ------ `id=0.0933659066519 Comments from the Wiki `__ .. cfunction:: void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1=3, int param2=0, double param3=0, double param4=0) 指定の手法で画像を平滑化します. :param src: 入力画像. :param dst: 出力画像. :param smoothtype: 平滑化の手法: * **CV_BLUR_NO_SCALE** :math:`\texttt{param1}\times \texttt{param2}` のボックスカーネル(すべてが1)との線形畳み込み.異なるピクセルを異なるサイズのボックスフィルタで平滑化したい場合は, :ref:`Integral` によって求められる積分画像を利用します. * **CV_BLUR** :math:`\texttt{param1}\times\texttt{param2}` のボックスカーネル(すべてが1)との線形畳み込み.その後に, :math:`1/(\texttt{param1}\cdot\texttt{param2})` のスケーリングを行います. * **CV_GAUSSIAN** :math:`\texttt{param1}\times\texttt{param2}` のガウシアンカーネルとの線形畳み込み. * **CV_MEDIAN** :math:`\texttt{param1}\times\texttt{param1}` の正方アパーチャのメディアンフィルタ. * **CV_BILATERAL** :math:`\texttt{param1}\times\texttt{param1}` の正方アパーチャのバイラテラルフィルタ.パラメータは, color sigma= ``param3`` , spatial sigma= ``param4`` です. ``param1=0`` ならば,アパーチャの1辺は ``cvRound(param4*1.5)*2+1`` にセットされます.バイラテラルフィルタに関する情報は, http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/MANDUCHI1/Bilateral\_Filtering.html を参照してください :param param1: 1番目の平滑化パラメータである,アパーチャの幅.正の奇数 (1, 3, 5, ...) でなければいけません. :param param2: 平滑化パラメータ2.平滑化手法が,スケーリング有り/無しの単純平滑またはガウシアン平滑化の場合,この ``param2`` が 0 ならば,ここには ``param1`` の値がセットされます. :param param3: ガウシアン平滑化の場合,このパラメータがガウス分布の :math:`\sigma` (標準偏差)を示します.これが0の場合,以下のようにカーネルサイズから計算されます: .. math:: \sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{param1} for horizontal kernel} \\ \mbox{\texttt{param2} for vertical kernel} \end{array} 小さいサイズのカーネル( :math:`3\times 3` から :math:`7\times 7` )の場合は,標準の sigma を用いた方が高速に計算できます.この ``param3`` が 0 ではなく,かつ ``param1`` と ``param2`` が 0 の場合,(処理に十分な精度を得るために)カーネルサイズは sigma から計算されます この関数は,指定された手法を用いて画像の平滑化を行います.各手法には,以下に示すような特徴と制限があります. スケーリングなしの平滑化は,シングルチャンネル画像に対してのみ適用でき,( :ref:`Sobel` や :ref:`Laplace` と同様に)8ビットから16ビットフォーマットへの累積計算や,32ビット浮動小数点数から32ビット浮動小数点数への累積計算をサポートします. 単純平滑化とガウシアン平滑化は,1チャンネル,あるいは3チャンネル,8ビット,16ビット,32ビット浮動小数点型の画像をサポートします.また,これら2つの手法は,置換モードで画像を処理することができます. メディアンフィルタとバイラテラルフィルタは,1チャンネル,あるいは3チャンネル,8ビット画像に適用でき,置換モードでの処理は行えません. .. index:: Sobel .. _Sobel: Sobel ----- `id=0.305362512947 Comments from the Wiki `__ .. cfunction:: void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int apertureSize=3 ) 拡張 Sobel オペレータを用いて1次,2次,3次または混合次数の微分画像を求めます. :param src: CvArr* 型の入力画像. :param dst: 出力画像. :param xorder: x 方向の微分次数. :param yorder: y 方向の微分次数. :param apertureSize: 拡張 Sobel カーネルのサイズ,1,3,5,7 のいずれかです. ``aperatureSize`` = 1 の場合を除いて, :math:`\texttt{apertureSize} \times \texttt{apertureSize}` の,(2つのベクトルの積に)分離可能なカーネルが微分画像の計算に用いられます. :math:`\texttt{apertureSize} = 1` の場合は, :math:`3 \times 1` または :math:`1 \times 3` のカーネルが用いられます(ガウシアンによる平滑化は行われません).また,特別な値である ``CV_SCHARR`` (-1) は, :math:`3\times3` の Sobel より精度が良い :math:`3\times3` の Scharr フィルタに対応します.この Scharr のアパーチャは以下のようになります. .. math:: \vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3} これは x-方向微分に対するカーネルであり,転置すれば y-方向微分に対するカーネルとなります. この関数は,以下のように,画像と適切なカーネルの畳み込みによって微分画像を求めます: .. math:: \texttt{dst} (x,y) = \frac{d^{xorder+yorder} \texttt{src}}{dx^{xorder} \cdot dy^{yorder}} Sobel オペレータは,ガウシアンによる平滑化と微分の組み合わせなので,その結果はノイズに対して多少は頑健です.1次の x-あるいは,y-微分画像を求める場合は大抵,この関数は次のような引数で呼び出されます:( ``xorder`` = 1, ``yorder`` = 0, ``apertureSize`` = 3) あるいは ( ``xorder`` = 0, ``yorder`` = 1, ``apertureSize`` = 3).最初の例は,以下のカーネルに対応します: .. math:: \vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1} また,2番目の例は,以下のカーネルに対応します: .. math:: \vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1} または, .. math:: \vecthreethree{1}{2}{1}{0}{0}{0}{-1}{2}{-1} どちらのカーネルになるかは,元画像の原点(構造体 ``IplImage`` のフィールド ``origin`` )に依存します.スケーリングは行われないので,出力画像の各ピクセル値は,ほとんどの場合入力画像のそれよりも大きな値になります.そこでオーバーフローを避けるために,例えば入力画像が8ビットの場合,出力画像として16ビット画像を指定する必要があります.このような16ビット画像は,関数 :ref:`ConvertScale` か :ref:`ConvertScaleAbs` を用いて 8ビット画像に戻すことができます.またこの関数は,8ビット画像だけでなく32ビット浮動小数点型画像も処理可能です.ただし,入力画像,出力画像共に,同じサイズ,あるいは同じ ROI サイズのシングルチャンネル画像である必要があります.