高斯函數(shù)在學(xué)術(shù)領(lǐng)域運用的非常廣泛。 寫工程產(chǎn)品的時候,經(jīng)常用它來去除圖片或者視頻的噪音司致,平滑圖片, Blur處理。我們今天來看看高斯濾波, Gaussian Filter聋迎。
1D的高斯函數(shù)
一維的高斯函數(shù)(或者叫正態(tài)分布)方程跟圖形如下:
是均值脂矫; 是標(biāo)準(zhǔn)方差。它有個重要特點是 - 到+ 之間的G(x)與x軸圍成的面積占全部面積的68.2%. -2 到+2之間的面積占95%霉晕。-3 到+3之間的面積占99.7%庭再。
如果我們給-3 到+3區(qū)間, 它幾乎包括了所有可能的點捞奕。這個特性對Filter kernel的生成很重要。
2D的高斯函數(shù)
所謂高斯濾波操作拄轻,其實就是用高斯函數(shù)對image做卷積計算颅围。但一般圖像在計算機中一般是離散的3D矩陣,而高斯函數(shù)是連續(xù)函數(shù)恨搓,所以我們要從連續(xù)高斯函數(shù)中采樣生成離散的2D矩陣院促,即Gaussian Filter Kernel。 我們可以控制Kernal的size奶卓,讓它的點都落在-3 到+3區(qū)間內(nèi)一疯。
生成高斯kernel
// Function to create Gaussian filter; sigma is standard deviation
Matrix getGaussian(int height, int width, double sigma)
{
Matrix kernel(height, Array(width));
// sum is for normalization
double sum=0.0;
int i,j;
// generating the kernel
for (i=0 ; i<height ; i++) {
for (j=0 ; j<width ; j++) {
// using gaussian function to generate gaussian filter
kernel[i][j] = exp(-(i*i+j*j)/(2*sigma*sigma))/(2*M_PI*sigma*sigma);
sum += kernel[i][j];
}
}
// normalising the Kernel
for (i=0 ; i<height ; i++) {
for (j=0 ; j<width ; j++) {
kernel[i][j] /= sum;
}
}
return kernel;
}
比如,我們用高斯函數(shù)生成了一個5x5夺姑, 是1的高斯核2D矩陣:
它有幾個特點:
- 最中間的值最大墩邀,值向周圍遞減
- 越大,高斯函數(shù)的峰越寬盏浙,臨接的數(shù)值差越大
對圖片應(yīng)用高斯Filter
對某個像素點image[i][j]眉睹,F(xiàn)itler對原圖對應(yīng)的像素點做點乘,相加废膘。 生成新的值竹海。
材料來源
Image applyFilter(Image &image, Matrix &filter){
assert(image.size()==3 && filter.size()!=0);
int height = image[0].size();
int width = image[0][0].size();
int filterHeight = filter.size();
int filterWidth = filter[0].size();
int newImageHeight = height-filterHeight+1;
int newImageWidth = width-filterWidth+1;
int d,i,j,h,w;
Image newImage(3, Matrix(newImageHeight, Array(newImageWidth)));
// iter the image pixel
for (d=0 ; d<3 ; d++) {
for (i=0 ; i<newImageHeight ; i++) {
for (j=0 ; j<newImageWidth ; j++) {
// using filter convolute the image matrix
for (h=i ; h<i+filterHeight ; h++) {
for (w=j ; w<j+filterWidth ; w++) {
newImage[d][i][j] += filter[h-i][w-j]*image[d][h][w];
}
}
}
}
}
return newImage;
}
如下圖,圖片被平滑處理了丐黄。