高斯核心矩陣 如何計算 範例程式
取自 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;
沒有留言:
張貼留言