Opencv学習(1):ガウスフィルタリング


楽しいエビhttp://blog.csdn.net/lights_joy/
転載を歓迎しますが、作者の情報を残してください.
本論文はopencv 3..0に適用され、vs 2013
Opencvではガウスフィルタ関数が提供されます.
/** @brief Blurs an image using a Gaussian filter.

The function convolves the source image with the specified Gaussian kernel. In-place filtering is
supported.

@param src input image; the image can have any number of channels, which are processed
independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must be
positive and odd. Or, they can be zero's and then they are computed from sigma.
@param sigmaX Gaussian kernel standard deviation in X direction.
@param sigmaY Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be
equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height,
respectively (see cv::getGaussianKernel for details); to fully control the result regardless of
possible future modifications of all this semantics, it is recommended to specify all of ksize,
sigmaX, and sigmaY.
@param borderType pixel extrapolation method, see cv::BorderTypes

@sa  sepFilter2D, filter2D, blur, boxFilter, bilateralFilter, medianBlur
 */
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                                double sigmaX, double sigmaY = 0,
                                int borderType = BORDER_DEFAULT );
今回はその実現と使用を学びます.
1.    ガウス関数の定義
ガウス関数の形式は:

a、bとcは実数定数であり、a>0.
a=1、b=0、c=1の場合、この関数の図形は以下の通りです.
Opencv学习(1):高斯滤波_第1张图片
上記の3つのパラメータのうち、aはピークの値を制御し、bは中心点が0点から離れた値を制御し、cは上昇速度を制御する.
a=2,b=1,c=0.5の場合の図形は以下のようになり、この影響が顕著に見られた.
Opencv学习(1):高斯滤波_第2张图片
2.    平滑化処理におけるガウス関数
Gauss関数の分離性のために,Opencvは二次元Gauss関数を積分して,まず画像を一次元Gauss関数と畳み込みし,次に畳み込み結果を方向に垂直な同じ一次元Gauss関数と畳み込みした.各方向に1次元の畳込みがあり、ガウス関数の形は次のようになります.

ここのksizeは選択された核サイズで、iは核関数の中の点の番号を計算します.
ここでのアルファは正規化係数であり、計算されたksize個数の和は1であることを保証するために使用される.
sigma<=0の場合、計算式は、sigma=0.3*((ksize-1)*0.5-1)+0.8.
sigma>0は、この入力パラメータsigmaを使います. 
OpencvにおけるGaussコアの生成は関数getGaussianKernelによって行われる.
cv::Mat cv::getGaussianKernel( int n, double sigma, int ktype )
{
    const int SMALL_GAUSSIAN_SIZE = 7;
    static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] =
    {
        {1.f},
        {0.25f, 0.5f, 0.25f},
        {0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f},
        {0.03125f, 0.109375f, 0.21875f, 0.28125f, 0.21875f, 0.109375f, 0.03125f}
    };

    const float* fixed_kernel = n % 2 == 1 && n <= SMALL_GAUSSIAN_SIZE && sigma <= 0 ?
        small_gaussian_tab[n>>1] : 0;

    CV_Assert( ktype == CV_32F || ktype == CV_64F );
    Mat kernel(n, 1, ktype);
    float* cf = kernel.ptr();
    double* cd = kernel.ptr();

    double sigmaX = sigma > 0 ? sigma : ((n-1)*0.5 - 1)*0.3 + 0.8;
    double scale2X = -0.5/(sigmaX*sigmaX);
    double sum = 0;

    int i;
    for( i = 0; i < n; i++ )
    {
        double x = i - (n-1)*0.5;
        double t = fixed_kernel ? (double)fixed_kernel[i] : std::exp(scale2X*x*x);
        if( ktype == CV_32F )
        {
            cf[i] = (float)t;
            sum += cf[i];
        }
        else
        {
            cd[i] = t;
            sum += cd[i];
        }
    }

    sum = 1./sum;
    for( i = 0; i < n; i++ )
    {
        if( ktype == CV_32F )
            cf[i] = (float)(cf[i]*sum);
        else
            cd[i] *= sum;
    }

    return kernel;
}
この関数は実は簡単です.注意が必要です.
sigma<=0の場合、sigma=0.3*((ksize-1)*0.5-1)+0.8.
ksizeが確定したら、実はそれは定数です.

の計算結果も定数です.Opencvは計算速度を上げるために、ksizeが小さい時に直接これらの定数値をコードに書いてください.即ちsmall_です.ガスケット.tabという配列の値(この配列は入力されたsigmaパラメータ(=0の場合のみ有効です).
3.    sigmaのフィルタ結果への影響
上記の解析から,ガウスフィルタ幅(平滑度を決定する)はパラメータによるものであることがわかった.σキャラクタリゼーションσ平滑度との関係はとても簡単です.σ大きいほどガウスフィルタの周波数帯域は広くなり、平滑度が良くなり、画像もぼやけます.平滑度パラメータの調整によりσ,画像の特徴があまりにもぼやけている(平滑化しすぎている)と平滑化された画像において、ノイズと微細なテクスチャによる過剰な突然変異量(不平滑化)との間でトレードオフが可能である.
同じ核の大きさを5と比較します.
sigmaが1の場合:
Opencv学习(1):高斯滤波_第3张图片
シグマが3の時:
Opencv学习(1):高斯滤波_第4张图片
後者の方が明らかにぼかしさが高いです.