圖1. N維空間常態分佈方程(該公式與圖2的是同一個)
高斯模糊是一種映像模糊濾波器,它用常態分佈計算映像中每個像素的變換。
N 維空間常態分佈方程為
(圖2)
在二維空間定義為
(圖3)
其中 r 是模糊半徑 (r2 = u2 + v2),σ 是常態分佈的標準差。
在二維空間中,這個公式產生的曲面的等高線是從中心開始呈常態分佈的同心圓。分布不為零的像素組成的卷積矩陣與原始映像做變換。
/*
e的x次方的函數
如
exp(1) = e的1次方 = e = 2.718281828...
exp(0) = e的0次方 = 1
exp(2)= e的平方 = 7.3890561...
e是一個常數,等於 2.718281828...
*/
一個標準差為1.4的高斯5x5的卷積核:
2 4 5 4 2
4 9 12 9 4
5 12 15 12 5
4 9 12 9 4
2 4 5 4 2
最後乘以比例係數 1/115
// 代碼
// 代碼1(自己實現的)
void MakeGauss()
{
double sigma = 1.4; // σ是常態分佈的標準差 這裡為 1.4
double dResult[5][5]; // 用於儲存結果
double dResult1[5][5]; // 用於儲存結果
// 數組的中心點
int nCenterX = 2, nCenterY = 2; // 中心點位置以1開始的吧
int nSize = 5;
// 數組的某一點到中心點的距離
double dDis;
double PI = 3.1415926535;
// 中間變數
double dValue;
double dSum ;
dSum = 0 ;
int i, j;
for(i = 0; i< nSize; ++i)
{
for(j = 0; j < nSize; ++j)
{
dDis = (i - nCenterX) * (i - nCenterX) + (j - nCenterY) * (j - nCenterY);
dValue = exp( - dDis / (2 * sigma * sigma)) /
(2 * PI * sigma * sigma);
dResult[i][j] = dValue;
dSum += dValue;
}
}
// 歸一化
for(i = 0; i< nSize; ++i)
{
for(j = 0; j < nSize; ++j)
{
dResult1[i][j] = dResult[i][j] / dSum;
}
}
std::cout << dSum << std::endl;
for(i = 0; i< nSize; ++i)
{
for(j = 0; j < nSize; ++j)
{
// dResult1才是高斯的結果, 但是dResult * 1.95 * 100卻得到了文章上說的結果
// 一個標準差為1.4的高斯5x5的卷積核
// 暫時不知道為什麼。
std::cout << (int)(dResult[i][j] * 1.95 * 100) << " ";
}
std::cout << std::endl;
}
}
// 代碼2(網上找的)
void Gauss()
{
int h_size;
float siz,sigma;
int i, j;
printf("Please input size of gaussian core/n");
scanf("%d",&h_size);
printf("Please input sigma:/n");
scanf("%f",&sigma);
siz=(h_size-1)/2;
float **a,**b;
a=new float*[h_size];
for(int i=0;i<h_size;i++) a[i]=new float[h_size];
b=new float*[h_size];
for( i=0;i<h_size;i++) b[i]=new float[h_size];
for(i=0;i<h_size;i++)
{
for(j=0;j<h_size;j++)
{
a[i][j]=-siz+j;
printf("%4.2f ",a[i][j]);
}
printf("/n");
}
printf("/n");
for( i=0;i<h_size;i++)
{
for(j=0;j<h_size;j++)
{
b[i][j]=a[j][i];
printf("%4.2f ",b[i][j]);
}
printf("/n");
}
printf("/n");
float h_sum=0;
for( i=0;i<h_size;i++)
{
for(j=0;j<h_size;j++)
{
a[i][j]=a[i][j]*a[i][j];
b[i][j]=b[i][j]*b[i][j];
a[i][j]=-(a[i][j]+b[i][j])/(2*sigma*sigma);
a[i][j]=exp(a[i][j]);
if(a[i][j]<0.0001) a[i][j]=0;
h_sum=h_sum+a[i][j];
}
}
for(i=0;i<h_size;i++)
{
for(j=0;j<h_size;j++)
{
a[i][j]=a[i][j]/h_sum;
}
}
for(i=0;i<h_size;i++)
{
for(j=0;j<h_size;j++)
{
printf("%4.4f ",a[i][j]);
}
printf("/n");
}
}