このセクションで述べる関数およびクラスを利用して, ( Mat() で表現された) 2次元画像に対して,様々な線形・非線形のフィルタリング処理を行います.このフィルタリング処理では,入力画像の各ピクセル位置 の近傍領域(通常は矩形)を利用して出力値を求めます.この出力は,線形フィルタの場合はピクセル値の重み付き和,モルフォロジー演算の場合は,最大値・最小値となります.求められた出力は,出力画像上の同じ位置 に保存されます.これはつまり,出力画像が入力画像と同じサイズになることを意味します.また通常,関数はマルチチャンネル配列をサポートしており,各チャンネルが個別に処理されるので,出力画像のチャンネル数も入力画像と同じ数になります.
このセクションで述べる関数とクラスに共通するもう1つの特徴は,これらは単純な算術関数とは異なり,存在しないピクセルの値を外挿する必要があるということです.例えば, のガウシアンフィルタを用いて画像の平滑化を行いたい場合,各行の左端のピクセルを処理する際に,さらにその左側,つまり,画像外のピクセルが必要となります.このようなピクセルを,画像の左端のピクセルと同じものだと仮定する(つまり,「複製境界」外挿法),あるいは,存在しないすべてのピクセルを 0 とする(つまり,「定数境界」外挿法)などの処理が可能です. OpenCV では,ユーザがこの外挿手法を指定することができます.関数 borderInterpolate() および,以下で述べる様々な関数のパラメータ borderType の説明を参照してください.
1列カーネルを用いたフィルタの基底クラス.
class BaseColumnFilter
{
public:
virtual ~BaseColumnFilter();
// ユーザによってオーバーライドされます.
//
// 入力の "dstcount + ksize - 1" 行目と,
// 出力の "dstcount" 行目という
// 行の集合に対して,フィルタリングオペレータを実行します.
// 各入力行と出力行は, "width" 個の要素をもちます.
// フィルタリング処理された行は "dst" バッファに書き込まれます.
virtual void operator()(const uchar** src, uchar* dst, int dststep,
int dstcount, int width) = 0;
// フィルタ状態をリセットします( IIR フィルタで必要になる場合がある)
virtual void reset();
int ksize; // アパーチャサイズ
int anchor; // アンカー点の位置,
// 通常,処理中には利用されません.
};
BaseColumnFilter クラスは,1列カーネルを用いたフィルタリングのための基底クラスです.このフィルタリングは,必ずしも線形処理である必要はありません.一般的に,この処理は次のように書かれます:
ここで はフィルタリング関数ですが,実際にはクラスとして表現されています.それによる副次的な影響が発生することもありますし,クラスなので以前に処理したデータを記憶しておくことも可能です.このクラスは,インタフェースを定義するだけで直接は利用されません.その代わり,OpenCV には具体的なフィルタリング処理を実装した派生クラスへのポインタを返す関数が複数存在します(そして,ユーザが追加することも可能です).これらのポインタは, FilterEngine() コンストラクタに渡されます.フィルタリング処理のインタフェースは uchar 型を利用しますが,個々の実装は8ビットデータに限定されません.
参考: BaseRowFilter() , BaseFilter() , FilterEngine() , getColumnSumFilter() , getLinearColumnFilter() , getMorphologyColumnFilter()
2次元画像フィルタの基底クラス.
class BaseFilter
{
public:
virtual ~BaseFilter();
// ユーザによってオーバーライドされます.
//
// 入力の "dstcount + ksize.height - 1" 行目と,
// 出力の "dstcount" 行目という
// 行の集合に対して,フィルタリングオペレータを実行します.
// 各入力行は "(width + ksize.width-1)*cn" 個の要素をもち,
// 各出力行は "width*cn" 個の要素をもちます.
// フィルタリング処理された行は "dst" バッファに書き込まれます.
virtual void operator()(const uchar** src, uchar* dst, int dststep,
int dstcount, int width, int cn) = 0;
// フィルタ状態をリセットします( IIR フィルタで必要になる場合がある)
virtual void reset();
Size ksize;
Point anchor;
};
BaseFilter クラスは,2次元カーネルを利用したフィルタリングのための基底クラスです.このフィルタリングは,必ずしも線形処理である必要はありません.一般的に,この処理は次のように書かれます:
ここで はフィルタリング関数を表します.このクラスは,インタフェースを定義するだけで直接は利用されません.その代わり,OpenCV には具体的なフィルタリング処理を実装した派生クラスへのポインタを返す関数が複数存在します(そして,ユーザが追加することもできます).これらのポインタは, FilterEngine() コンストラクタに渡されます.フィルタリング処理のインタフェースは uchar 型を利用しますが,個々の実装は8ビットデータに限定されません.
参考: BaseColumnFilter() , BaseRowFilter() , FilterEngine() , getLinearFilter() , getMorphologyFilter()
1行カーネルを用いたフィルタの基底クラス.
class BaseRowFilter
{
public:
virtual ~BaseRowFilter();
// ユーザによってオーバーライドされます.
//
// "width" 個の要素を持つ1入力行に対して,フィルタリング処理を行います.
// 各要素は, "cn" チャンネルをもちます.
// フィルタリング処理された行は "dst" バッファに書き込まれます.
virtual void operator()(const uchar* src, uchar* dst,
int width, int cn) = 0;
int ksize, anchor;
};
BaseRowFilter クラスは,1行カーネルを用いたフィルタリングのための基底クラスです.このフィルタリングは,必ずしも線形処理である必要はありません.一般的に,この処理は次のように書かれます:
ここで はフィルタリング関数を表します.このクラスは,インタフェースを定義するだけで直接は利用されません.その代わり,OpenCV には具体的なフィルタリング処理を実装した派生クラスへのポインタを返す関数が複数存在します(そして,ユーザが追加することもできます).これらのポインタは, FilterEngine() コンストラクタに渡されます.フィルタリング処理のインタフェースは uchar 型を利用しますが,個々の実装は8ビットデータに限定されません.
参考: BaseColumnFilter() , Filter() , FilterEngine() , getLinearRowFilter() , getMorphologyRowFilter() , getRowSumFilter()
汎用画像フィルタリングクラス.
class FilterEngine
{
public:
// 引数をとらないコンストラクタ
FilterEngine();
// 2次元の非分離型フィルタ (!_filter2D.empty()) あるいは
// 分離型フィルタ (!_rowFilter.empty() && !_columnFilter.empty()) を作成します.
// 入力データの型は "srcType" ,出力データの型は "dstType"
// 中間データの型は "bufType" となります.
// _rowBorderType と_columnBorderType は,画像外の値が
// どのように外挿補間されるかを決定します.
// _borderValue は, _rowBorderType と _columnBorderType の片方,
// あるいは両方が == cv::BORDER_CONSTANT である場合にのみ利用されます.
FilterEngine(const Ptr<BaseFilter>& _filter2D,
const Ptr<BaseRowFilter>& _rowFilter,
const Ptr<BaseColumnFilter>& _columnFilter,
int srcType, int dstType, int bufType,
int _rowBorderType=BORDER_REPLICATE,
int _columnBorderType=-1, // デフォルトでは _rowBorderType を利用
const Scalar& _borderValue=Scalar());
virtual ~FilterEngine();
// フィルタリングエンジン初期化のための別関数
void init(const Ptr<BaseFilter>& _filter2D,
const Ptr<BaseRowFilter>& _rowFilter,
const Ptr<BaseColumnFilter>& _columnFilter,
int srcType, int dstType, int bufType,
int _rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1,
const Scalar& _borderValue=Scalar());
// サイズ "wholeSize" の画像中の ROI に対してフィルタリングを開始します.
// 元画像における開始点の y 座標を返します.
virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1);
// "wholeSize" の代わりに画像自身を引数にとる,
// start のもう1つの形式.isolated を true に設定すると,
// ROI の外側には実際のピクセルが存在しないことになります.
// (指定の境界モードで,ピクセルを外挿補間したい場合に利用します)
virtual int start(const Mat& src, const Rect& srcRoi=Rect(0,0,-1,-1),
bool isolated=false, int maxBufRows=-1);
// 入力画像の次の部分画像,つまり
// "src" から始まる "srcCount" 行分を処理し,
// 結果を "dst" に格納します.
// また,作成された行数を返します.
virtual int proceed(const uchar* src, int srcStep, int srcCount,
uchar* dst, int dstStep);
// ROI 全体,あるいは画像全体を,
// 一度の関数呼び出しで処理する高レベル関数
virtual void apply( const Mat& src, Mat& dst,
const Rect& srcRoi=Rect(0,0,-1,-1),
Point dstOfs=Point(0,0),
bool isolated=false);
bool isSeparable() const { return filter2D.empty(); }
// 入力画像のうち,まだ処理されていない行数
int remainingInputRows() const;
// 出力行のうち,まだ作成されていない行数
int remainingOutputRows() const;
...
// 入力画像における,開始行と終了行
int startY, endY;
// フィルタへのポインタ
Ptr<BaseFilter> filter2D;
Ptr<BaseRowFilter> rowFilter;
Ptr<BaseColumnFilter> columnFilter;
};
FilterEngine クラスは,画像に任意のフィルタリング処理を適用する目的で利用できます.これは,必要なすべての中間バッファを含み,画像外の「仮想的な」ピクセルを,外挿補間によって求めます.後に述べる様々な create*Filter 関数によって,初期化された FilterEngine インスタンスへのポインタが返されます.これらは, filter2D() , erode() , dilate() などの高レベル関数の内部で利用されます.つまりこのクラスは,OpenCV の多くのフィルタリング関数の要と言えるでしょう.
このクラスによって,フィルタリング処理と,色空間の変換,閾値処理,算術処理などの別の処理とを容易に組み合わせることができます(それでも,非常に簡単になるわけではありませんが).複数の処理を組み合わせるとデータがキャッシュされるので,非常に効率が良くなります.例えば次の例は,浮動小数点型の画像に対するラプラスオペレータであり, Laplacian() を単純化したものです.
void laplace_f(const Mat& src, Mat& dst)
{
CV_Assert( src.type() == CV_32F );
dst.create(src.size(), src.type());
// d2I/dx2 の微分平滑化カーネルを得ます.
// d2I/dy2 に対しても,kd と ks を入れ替えただけの同じカーネルが利用できます.
Mat kd, ks;
getSobelKernels( kd, ks, 2, 0, ksize, false, ktype );
// 10 行を一度に処理します.
int DELTA = std::min(10, src.rows);
Ptr<FilterEngine> Fxx = createSeparableLinearFilter(src.type(),
dst.type(), kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );
Ptr<FilterEngine> Fyy = createSeparableLinearFilter(src.type(),
dst.type(), ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() );
int y = Fxx->start(src), dsty = 0, dy = 0;
Fyy->start(src);
const uchar* sptr = src.data + y*src.step;
// 空間微分画像のためのバッファを確保します.
// 最後の反復で,出力は入力よりも大きい
// max(kd.rows-1,ks.rows-1) 行となるので,
// このバッファは, DELTA 行より大きい必要があります.
Mat Ixx( DELTA + kd.rows - 1, src.cols, dst.type() );
Mat Iyy( DELTA + kd.rows - 1, src.cols, dst.type() );
// ループ内部では,常に DELTA 行がフィルタに渡されます
// ( "start" メソッド内で実際の画像の高さが与えられているので,
// "proceed" メソッドはオーバーフローの危険にも対処できます)
// 出力として,次のような値が得られます:
// * < DELTA rows (初期のバッファ累積段階)
// * = DELTA rows (途中の安定状態)
// * > DELTA rows (そして,入力画像の最後に到達した状態.
// 境界モードを利用して「仮想的な」行を生成し,それをフィルタリングします)
// この出力行数を表す変数は dy です.
// dsty は,現在の出力行,
// sptr は,処理される最初の入力行へのポインタ,となります.
for( ; dsty < dst.rows; sptr += DELTA*src.step, dsty += dy )
{
Fxx->proceed( sptr, (int)src.step, DELTA, Ixx.data, (int)Ixx.step );
dy = Fyy->proceed( sptr, (int)src.step, DELTA, d2y.data, (int)Iyy.step );
if( dy > 0 )
{
Mat dstripe = dst.rowRange(dsty, dsty + dy);
add(Ixx.rowRange(0, dy), Iyy.rowRange(0, dy), dstripe);
}
}
}
フィルタリング処理の細かい制御が不要ならば,単純に FilterEngine::apply メソッドを利用することができます.ここでは,このメソッドが実際にどのように実装されているのかを示します:
void FilterEngine::apply(const Mat& src, Mat& dst,
const Rect& srcRoi, Point dstOfs, bool isolated)
{
// 行列の型をチェックします.
CV_Assert( src.type() == srcType && dst.type() == dstType );
// 「画像全体」を扱う場合
Rect _srcRoi = srcRoi;
if( _srcRoi == Rect(0,0,-1,-1) )
_srcRoi = Rect(0,0,src.cols,src.rows);
// 出力先の ROI が dst 内部に収まっているかどうかチェックしてください.
// FilterEngine::start は,元の ROI が src 内部に収まっているかをチェックします.
CV_Assert( dstOfs.x >= 0 && dstOfs.y >= 0 &&
dstOfs.x + _srcRoi.width <= dst.cols &&
dstOfs.y + _srcRoi.height <= dst.rows );
// フィルタリング開始
int y = start(src, _srcRoi, isolated);
// ROI 全体を処理する. "endY - startY" は,
// 処理対象となる入力行の総数であることに注意してください
// (srcRoi の外側,かつ元画像の内側にある行も含みます).
proceed( src.data + y*src.step,
(int)src.step, endY - startY,
dst.data + dstOfs.y*dst.step +
dstOfs.x*dst.elemSize(), (int)dst.step );
}
以前のバージョンの OpenCV とは異なり,現在のフィルタリング処理は,画像の ROI 記法を完全にサポートします.つまり,ROI の外側かつ画像の内側にあるピクセルは,フィルタリング処理に利用されます.例えば,1ピクセルのROIに対してフィルタリング処理を行うことが可能で,つまり個々のピクセルに対するフィルタ応答を得ることができます(しかし, isolated=false を FilterEngine::start や FilterEngine::apply に渡すことで,以前の挙動をエミュレートすることは可能です) .ROI を明示的に FilterEngine::apply に渡したり,新しい行列ヘッダを作成したりすることができます:
// src(x,y) における微分 dI/dx を求めます.
// 方法 1:
// 1 つの値のための行列ヘッダを作成します.
float val1 = 0;
Mat dst1(1,1,CV_32F,&val1);
Ptr<FilterEngine> Fx = createDerivFilter(CV_32F, CV_32F,
1, 0, 3, BORDER_REFLECT_101);
Fx->apply(src, Rect(x,y,1,1), Point(), dst1);
// 方法 2:
// 1 つの値のための行列ヘッダを作成します.
float val2 = 0;
Mat dst2(1,1,CV_32F,&val2);
Mat pix_roi(src, Rect(x,y,1,1));
Sobel(pix_roi, dst2, dst2.type(), 1, 0, 3, 1, 0, BORDER_REFLECT_101);
printf("method1 =
データの型に注意してください. BaseFilter() の説明で述べたように, Base*Filter::operator() が uchar ポインタしかとることができないのに対して,個別のフィルタはあらゆる型のデータを処理することができます.よって,実際の型に関する情報は存在しません.これを機能させるために,以下のルールが利用されています:
参考: BaseColumnFilter() , BaseFilter() , BaseRowFilter() , createBoxFilter() ,
createDerivFilter() , createGaussianFilter() , createLinearFilter() , createMorphologyFilter() , createSeparableLinearFilter()
画像にバイラテラルフィルタを適用します.
パラメタ: |
|
---|
関数 bilateralFilter は,入力画像にバイラテラルフィルタを適用します.このフィルタについては, http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html で説明されています.
正規化されたボックスフィルタを用いて画像を平滑化します.
パラメタ: |
|
---|
関数 blur は,カーネルを用いて画像の平滑化を行います:
blur(src, dst, ksize, anchor, borderType) の呼び出しは, boxFilter(src, dst, src.type(), anchor, true, borderType) と等価です.
参考: boxFilter() , bilateralFilter() , GaussianBlur() , medianBlur() .
外挿されるピクセルの元となる座標を求めます.
パラメタ: |
|
---|
関数 borderInterpolate は,指定の外挿境界モードを利用した場合の,指定の外挿ピクセルに対応する元ピクセルの座標を求め,それを返します.例えば,水平方向に BORDER_WRAP ,垂直方向に BORDER_REFLECT_101 モードを用いて,浮動小数点型画像 img の「仮想」ピクセル Point(-5, 100) の値を求めたい場合,次のようになります.
float val = img.at<float>(borderInterpolate(100, img.rows, BORDER_REFLECT_101),
borderInterpolate(-5, img.cols, BORDER_WRAP));
通常,この関数が直接呼ばれることはありません.これは,高速に外挿を行うためのテーブルを計算する目的で FilterEngine() や copyMakeBorder() の内部で利用されます.
ボックスフィルタを用いて画像を平滑化します.
パラメタ: |
|
---|
関数 boxFilter は,カーネルを用いて画像の平滑化を行います:
ここで,
正規化されていないボックスフィルタは,(密なオプティカルフローアルゴリズムや などで利用される)微分画像の共分散行列などの,各ピクセル近傍領域の全体的特徴を求める際に役立ちます.様々なサイズの窓でピクセル値の合計を求める必要があるならば, integral() を利用してください.
参考: boxFilter() , bilateralFilter() , GaussianBlur() , medianBlur() , integral() .
画像のガウシアンピラミッドを作成します.
パラメタ: |
|
---|
関数 buildPyramid は,画像のベクトルを作成し,ガウシアンピラミッドを構築します.この作業は, dst[0]==src から開始され,1つ前に作られた画像ピラミッド層に pyrDown() を再帰的に適用することで構築されます.
画像のまわりに境界を作成します.
パラメタ: |
|
---|
関数 copyMakeBorder は,入力画像を出力画像の中央にコピーします.そして,コピーされた入力画像の上下左右の隙間は,外挿されたピクセルで埋められます.これは, FilterEngine() や,それに基づくフィルタリング関数(これらは,実行中にピクセルを外挿します)が行うようなものとは異なります.ユーザ定義関数を含む,より複雑な別の関数で画像境界を簡単に扱えるするためのものです.
この関数は src が既に dst の中央に存在するようなケースをサポートします.この場合, src 自身はコピーされず,単に境界だけ作成されます.例えば:
// 全方向の境界が同じ幅になるようにします.
int border=2;
// 画像と境界を合わせたものがフィットする大きな画像を作成します.
Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth());
// それの中央部分を選択します(データはコピーされません)
Mat gray(gray_buf, Rect(border, border, rgb.cols, rgb.rows));
// 画像を RGB からグレースケールに変換します
cvtColor(rgb, gray, CV_RGB2GRAY);
// 置換モードで境界を作成します
copyMakeBorder(gray, gray_buf, border, border,
border, border, BORDER_REPLICATE);
// 独自のフィルタリングを行う ...
...
ボックスフィルタエンジン.
パラメタ: |
|
---|
関数 createBoxFilter は,水平方向の総和を求める基本フィルタ getRowSumFilter() と,垂直方向の総和を求める基本フィルタ getColumnSumFilter() を作成し,新たに作成された FilterEngine() に両方の基本フィルタを渡す簡易関数です.作成されたフィルタエンジンは,正規化された,あるいは正規化されていないボックスフィルタを用いた画像フィルタリングに利用できます.
この関数自身は, blur() や boxFilter() で利用されます.
参考: FilterEngine() , blur() , boxFilter() .
微分画像を求めるためのエンジンを返します.
パラメタ: |
|
---|
関数 createDerivFilter() は, getDerivKernels() を用いて微分画像を求めるための線形フィルタ係数を取得し, createSeparableLinearFilter() によって分離型線形フィルタを作成する小さな簡易関数です.この関数は, Sobel() や Scharr() で利用されます.
参考: createSeparableLinearFilter() , getDerivKernels() , Scharr() , Sobel() .
ガウシアンフィルタによる画像の平滑化を行うエンジンを返します.
パラメタ: |
|
---|
関数 createGaussianFilter() は,ガウシアンカーネルを求め,そのカーネルを利用した分離型線形フィルタを返します.この関数は GaussianBlur() で利用されます.この関数は入力と出力に共通する1つのデータ型しか取りませんが, getGaussianKernel() を呼び出した後に直接 createSeparableFilter() を呼ぶことで,この制限を回避できます.
参考: createSeparableLinearFilter() , getGaussianKernel() , GaussianBlur() .
非分離型線形フィルタエンジンを作成します.
パラメタ: |
|
---|
関数 getLinearFilter は,指定のカーネルを利用し,入出力配列の型を満たす2次元線形フィルタへのポインタを返します.関数 createLinearFilter は, getLinearFilter を呼び出し,そこから取得した2次元フィルタを FilterEngine() のコンストラクタに渡す高レベル関数です.
参考: createSeparableLinearFilter() , FilterEngine() , filter2D()
非分離型モルフォロジー演算を行うエンジンを作成します.
パラメタ: |
|
---|
これらの関数は,基本的なモルフォロジー演算,または,それに基づくフィルタエンジンを作成します.通常は, createMorphologyFilter() ,あるいは同等の高レベル関数 erode() , dilate() , morphologyEx() を用いれば十分でしょう. createMorphologyFilter() は,構造要素の形状を分析し,構造要素が正方形である場合は分離型モルフォロジーフィルタエンジンを構築することに注意してください.
参考: erode() , dilate() , morphologyEx() , FilterEngine()
分離型線形フィルタエンジンを作成します.
パラメタ: |
|
---|
これらの関数は,基本的な分離型線形フィルタリング処理,またはそれに基づくフィルタエンジンを作成します.通常は, createSeparableLinearFilter() または同等の高レベル関数 sepFilter2D() を用いれば十分でしょう.関数 createMorphologyFilter() は賢いので,それぞれのカーネルに対する symmetryType ,中間値の bufType ,そして整数演算でフィルタリングされた場合にフィルタ係数にエンコードするための bits 数を算出します.これがうまく動作しないならば, getLinearColumnFilter , getLinearRowFilter を直接呼び出して,これらを FilterEngine() のコンストラクタに渡すこともできます.
参考: sepFilter2D() , createLinearFilter() , FilterEngine() , getKernelType()
指定の構造要素を用いて画像の膨張を行います.
パラメタ: |
|
---|
関数 dilate は,ピクセル近傍領域の形状を決定し,そこから最大値を取り出すような指定構造要素を用いて,入力画像の膨張を行います:
この関数は,置換モードをサポートします.膨張は複数( iterations )回適用することができます.また,マルチチャンネル画像の場合,各チャンネルは個別に処理されます.
指定の構造要素を用いて画像の収縮を行います.
パラメタ: |
|
---|
関数 erode は,ピクセル近傍領域の形状を決定し,そこから最小値を取り出すような指定構造要素を用いて,入力画像の収縮を行います:
この関数は,置換モードをサポートします.収縮は複数( iterations )回適用することができます.また,マルチチャンネル画像の場合,各チャンネルは個別に処理されます.
カーネルを用いて画像の畳み込みを行います.
パラメタ: |
|
---|
関数 filter2D は,任意の線形フィルタを画像に適用します.また,置換モードがサポートされます.アパーチャが部分的に画像外にはみ出す場合,関数は指定された境界モードに基づいてピクセル値を外挿補間します.
この関数は,実際には畳み込みではなく相関を求めます:
つまり,カーネルはアンカー点周りで対称ではありません.本当の畳み込みが必要ならば, flip() を用いてカーネルを反転し,新しいアンカー (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1) をセットしてください.
この関数は,十分に大きいカーネル( ~ )の場合は に基づくアルゴリズムを利用し,小さいカーネルの場合は( createLinearFilter() によって取得されるエンジンを用いる)直接アルゴリズムを利用します.
参考: sepFilter2D() , createLinearFilter() , dft() , matchTemplate()
ガウシアンフィルタを用いて画像の平滑化を行います.
パラメタ: |
|
---|
この関数は,指定のガウシアンかーネルを用いて入力画像の畳み込みを行います.また,置換モードのフィルタリングがサポートされます.
参考: sepFilter2D() , filter2D() , blur() , boxFilter() , bilateralFilter() , medianBlur()
画像の空間微分を求めるためのフィルタ係数を返します.
パラメタ: |
|
---|
関数 getDerivKernels は,画像の空間微分を求めるためのフィルタ係数を求め,それを返します. ksize=CV_SCHARR の場合は, の Scharr カーネルが生成されます. Scharr() を参照してください.そうでない場合は,Sobel カーネルが生成されます.同じく Sobel() を参照してください.これらのフィルタは通常, sepFilter2D() か createSeparableLinearFilter() に渡されます.
ガウシアンフィルタの係数を返します.
パラメタ: |
|
---|
関数 getGaussianKernel は, のガウシアンフィルタ係数行列を求め,それを返します.
ここで, であり, は となるように選ばれたスケールファクタです.
このように生成されたカーネルを2つ, sepFilter2D() あるいは createSeparableLinearFilter() に渡すことができます.これらは,渡されたカーネルが平滑化カーネルであることを自動的に検出して適切に扱います.また,高レベル関数 GaussianBlur() を使うこともできます.
参考: sepFilter2D() , createSeparableLinearFilter() , getDerivKernels() , getStructuringElement() , GaussianBlur() .
カーネルの種類を返す..
パラメタ: |
|
---|
The function analyzes the kernel coefficients and returns the corresponding kernel type:
- KERNEL_GENERAL 汎用カーネル - 対称でもなく,他の特徴もない場合
- KERNEL_SYMMETRICAL カーネルが対称: かつ,アンカーが中心にある
- KERNEL_ASYMMETRICAL カーネルが非対称: かつ,アンカーが中央にある
- KERNEL_SMOOTH すべてのカーネル要素が非負で,その合計が1.例えば,ガウシアンカーネルは smooth かつ symmetrical であるので,この関数は KERNEL_SMOOTH | KERNEL_SYMMETRICAL を返します
- KERNEL_INTEGER すべてのカーネル係数が整数値.このフラグは KERNEL_SYMMETRICAL あるいは KERNEL_ASYMMETRICAL と組み合わせることができます
モルフォロジー演算のために,指定されたサイズと形状の構造要素を返します.
パラメタ: |
|
---|
関数 getStructuringElement は, createMorphologyFilter() , erode() , dilate() または morphologyEx() に渡される構造要素を作成し,それを返します.しかし,任意の2値マスクを作成し,それを構造要素として利用することもできます.
メディアンフィルタを用いて画像の平滑化を行います.
パラメタ: |
|
---|
関数 medianBlur は,アパーチャサイズが であるメディアンフィルタを用いて,画像の平滑化を行います.マルチチャンネル画像の各チャンネルは,個別に処理されます.また,置換モード処理がサポートされます.
参考: bilateralFilter() , blur() , boxFilter() , GaussianBlur()
高度なモルフォロジー変換を行います.
パラメタ: |
|
---|
関数 morphologyEx は,収縮と膨張を基本演算として利用する高度なモルフォロジー変換を行います.
オープニング:
クロージング:
モルフォロジー勾配:
「トップハット変換」:
「ブラックハット変換」:
いずれの演算も置換モードをサポートします.
参考: dilate() , erode() , createMorphologyFilter()
画像のラプラシアンを求めます.
パラメタ: |
|
---|
関数 cvLaplace は,Sobelオペレータを用いて計算される x および y に関する2次微分を足し合わせることで,入力画像のラプラシアンを求めます.
ksize > 1 の場合は,上述のように動作します.また, ksize == 1 の場合は, のアパーチャを用いたフィルタリングによってラプラシアンを求めます.
画像の平滑化とダウンサンプリングを行います.
パラメタ: |
|
---|
関数 pyrDown は,ガウシアンピラミッド作成におけるダウンサンプリング部分を実行します.まず,以下のカーネルで入力画像の畳み込みを行います:
そして,偶数行と偶数列を読み飛ばすことで,画像のダウンサンプリングを行います.
画像のアップサンプリングと平滑化を行います.
パラメタ: |
|
---|
関数 pyrUp は,ガウシアンピラミッド作成におけるアップサンプリング部分を実行します(実際にラプラシアンピラミッドの作成に利用できます).まず,入力画像に 0 で埋められた偶数行,偶数列を挿入してアップサンプリングを行い, pyrDown() のときと同じカーネルを4倍したもので,その結果を畳み込みます.
画像に分離型線形フィルタを適用します.
パラメタ: |
|
---|
この関数は,画像に分離型線形フィルタを適用します.つまり,まず, src の各行に1次元カーネル rowKernel でフィルタリングを行います.次に,その結果の各列に対して1次元カーネル columnKernel でフィルタリングを行い,最終的な結果を delta だけシフトしたものが dst に格納されます.
参考: createSeparableLinearFilter() , filter2D() , Sobel() , GaussianBlur() , boxFilter() , blur() .
拡張 Sobel オペレータを用いて,1次,2次,3次または混合次数の微分画像を求めます.
パラメタ: |
|
---|
カーネルサイズ1を除くすべての場合で,微分画像を求めるために の分離型カーネルが用いられます. の場合は, または のカーネルが用いられます(つまり,ガウシアン平滑化は行われません). ksize = 1 は,1次または2次の,x- あるいは y-微分に関してのみ利用されます.
特別な値 ksize = CV_SCHARR (-1) も存在し,これは の Sobel よりも正確な結果を得ることができる のScharr フィルタを意味します.この Scharr アパーチャは以下のようになります.
これは x-導関数に対するカーネルであり,転置すれば y-導関数に対するカーネルとなります.
関数 sobel は,以下のように,画像と適切なカーネルの畳み込みによって微分画像を求めます:
Sobel オペレータは,ガウシアンによる平滑化と微分の組み合わせなので,その結果はノイズに対して多少は頑健です. 1次の x-あるいは,y-微分画像を求める場合は大抵,この関数は次のような引数で呼び出されます: ( xorder = 1, yorder = 0, ksize = 3) あるいは ( xorder = 0, yorder = 1, ksize = 3). 最初の例は,以下のカーネルに対応します:
また,2番目の例は,以下のカーネルに対応します:
参考: Scharr() , Lapacian() , sepFilter2D() , filter2D() , GaussianBlur()
Scharr オペレータを用いて,1次の x- あるいは y-微分画像を求めます.
パラメタ: |
|
---|
この関数は,Scharrオペレータを用いて,1次のx-あるいはy-微分画像を求めます.次の関数呼び出し
は,以下と等価になります.