圖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"); } }