2018年6月15日 星期五

高斯核心矩陣 如何計算 範例程式

高斯核心矩陣 如何計算 範例程式

取自 opencv 函式轉成一般 vector 函式
比較特別的是,他的計算方法如果半徑小於7的話,標準差sigma又是無效設置的話(小於1)就用內定的矩陣,而不再重新計算。
vector<double> getGaussianKernel( int n, double sigma )
{
    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;

    vector<double> kernel(n);
    double* cd = kernel.data();

    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);
        cd[i] = t;
        sum += cd[i];
    }

    sum = 1./sum;

    for( i = 0; i < n; i++ )
    {
        cd[i] *= sum;
    }

    return kernel;
}
使用範例
// 核心
    vector<double> gau = ::getGaussianKernel(3, 0);
    for (size_t i = 0; i < gau.size(); i++) {
        cout << gau[i] << ", ";
    } cout << endl;

// 驗證
    vector<double> gau = ::getGaussianKernel(9, 1.6);
    cout << "[";
    for (size_t i = 0; i < gau.size(); i++) {
        cout << gau[i] << ", " << endl;
    } cout << "]"<< endl;

    Mat g = cv::getGaussianKernel(9, 1.6);
    cout << g << endl;

沒有留言:

張貼留言