图像滤波之高斯滤波介绍
1?高斯濾波簡(jiǎn)介
了解高斯濾波之前,我們首先熟悉一下高斯噪聲。高斯噪聲是指它的概率密度函數(shù)服從高斯分布(即正態(tài)分布)的一類噪聲。如果一個(gè)噪聲,它的幅度分布服從高斯分布,而它的功率譜密度又是均勻分布的,則稱它為高斯白噪聲。高斯白噪聲的二階矩不相關(guān),一階矩為常數(shù),是指先后信號(hào)在時(shí)間上的相關(guān)性,高斯白噪聲包括熱噪聲和散粒噪聲。
高斯濾波器是一類根據(jù)高斯函數(shù)的形狀來(lái)選擇權(quán)值的線性平滑濾波器。高斯平滑濾波器對(duì)于抑制服從正態(tài)分布的噪聲非常有效。一維零均值高斯函數(shù)為:
???? g(x)=exp(?-x^2/(2?sigma^2)?
其中,高斯分布參數(shù)Sigma決定了高斯函數(shù)的寬度。對(duì)于圖像處理來(lái)說(shuō),常用二維零均值離散高斯函數(shù)作平滑濾波器,高斯函數(shù)的圖形:?
2?高斯濾波函數(shù)
對(duì)于圖像來(lái)說(shuō),高斯濾波器是利用高斯核的一個(gè)2維的卷積算子,用于圖像模糊化(去除細(xì)節(jié)和噪聲)。
1)?高斯分布
一維高斯分布:
? ??
二維高斯分布:
? ?
2)?高斯核
理論上,高斯分布在所有定義域上都有非負(fù)值,這就需要一個(gè)無(wú)限大的卷積核。實(shí)際上,僅需要取均值周圍3倍標(biāo)準(zhǔn)差內(nèi)的值,以外部份直接去掉即可。?如下圖為一個(gè)標(biāo)準(zhǔn)差為1.0的整數(shù)值高斯核。
?
3?高斯濾波性質(zhì)
高斯函數(shù)具有五個(gè)重要的性質(zhì),這些性質(zhì)使得它在早期圖像處理中特別有用.這些性質(zhì)表明,高斯平滑濾波器無(wú)論在空間域還是在頻率域都是十分有效的低通濾波器,且在實(shí)際圖像處理中得到了工程人員的有效使用.高斯函數(shù)具有五個(gè)十分重要的性質(zhì),它們是:?
(1)二維高斯函數(shù)具有旋轉(zhuǎn)對(duì)稱性,即濾波器在各個(gè)方向上的平滑程度是相同的.一般來(lái)說(shuō),一幅圖像的邊緣方向是事先不知道的,因此,在濾波前是無(wú)法確定一個(gè)方向上比另一方向上需要更多的平滑.旋轉(zhuǎn)對(duì)稱性意味著高斯平滑濾波器在后續(xù)邊緣檢測(cè)中不會(huì)偏向任一方向.?
(2)高斯函數(shù)是單值函數(shù).這表明,高斯濾波器用像素鄰域的加權(quán)均值來(lái)代替該點(diǎn)的像素值,而每一鄰域像素點(diǎn)權(quán)值是隨該點(diǎn)與中心點(diǎn)的距離單調(diào)增減的.這一性質(zhì)是很重要的,因?yàn)檫吘壥且环N圖像局部特征,如果平滑運(yùn)算對(duì)離算子中心很遠(yuǎn)的像素點(diǎn)仍然有很大作用,則平滑運(yùn)算會(huì)使圖像失真.?
(3)高斯函數(shù)的傅立葉變換頻譜是單瓣的.正如下面所示,這一性質(zhì)是高斯函數(shù)付立葉變換等于高斯函數(shù)本身這一事實(shí)的直接推論.圖像常被不希望的高頻信號(hào)所污染(噪聲和細(xì)紋理).而所希望的圖像特征(如邊緣),既含有低頻分量,又含有高頻分量.高斯函數(shù)付立葉變換的單瓣意味著平滑圖像不會(huì)被不需要的高頻信號(hào)所污染,同時(shí)保留了大部分所需信號(hào).?
(4)高斯濾波器寬度(決定著平滑程度)是由參數(shù)σ表征的,而且σ和平滑程度的關(guān)系是非常簡(jiǎn)單的.σ越大,高斯濾波器的頻帶就越寬,平滑程度就越好.通過(guò)調(diào)節(jié)平滑程度參數(shù)σ,可在圖像特征過(guò)分模糊(過(guò)平滑)與平滑圖像中由于噪聲和細(xì)紋理所引起的過(guò)多的不希望突變量(欠平滑)之間取得折衷.?
(5)由于高斯函數(shù)的可分離性,較大尺寸的高斯濾波器可以得以有效地實(shí)現(xiàn).二維高斯函數(shù)卷積可以分兩步來(lái)進(jìn)行,首先將圖像與一維高斯函數(shù)進(jìn)行卷積,然后將卷積結(jié)果與方向垂直的相同一維高斯函數(shù)卷積.因此,二維高斯濾波的計(jì)算量隨濾波模板寬度成線性增長(zhǎng)而不是成平方增長(zhǎng).
4?高斯濾波應(yīng)用
高斯濾波后圖像被平滑的程度取決于標(biāo)準(zhǔn)差。它的輸出是領(lǐng)域像素的加權(quán)平均,同時(shí)離中心越近的像素權(quán)重越高。因此,相對(duì)于均值濾波(mean?filter)它的平滑效果更柔和,而且邊緣保留的也更好。
高斯濾波被用作為平滑濾波器的本質(zhì)原因是因?yàn)樗且粋€(gè)低通濾波器,見(jiàn)下圖。而且,大部份基于卷積平滑濾波器都是低通濾波器。
?
??????? ?圖.高斯濾波器(標(biāo)準(zhǔn)差=3像素)的頻率響應(yīng)。The?spatial?frequency?axis?is?marked?
??????????? in?cycles?per?pixel,?and?hence?no?value?above?0.5?has?a?real?meaning。
5?高斯濾波步驟
?(1)移動(dòng)相關(guān)核的中心元素,使它位于輸入圖像待處理像素的正上方?
?(2)將輸入圖像的像素值作為權(quán)重,乘以相關(guān)核?
?(3)將上面各步得到的結(jié)果相加做為輸出?
?
6?高斯濾波源碼(C語(yǔ)言版)
1 // gaosilvbo.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 2 // 3 4 #include "stdafx.h" 5 #include <stdlib.h> 6 #include <math.h> 7 8 typedef unsigned long DWORD; 9 typedef long LONG; 10 typedef unsigned short WORD; 11 typedef unsigned char BYTE; 12 13 typedef struct tagRGBQUAD { 14 BYTE rgbBlue; 15 BYTE rgbGreen; 16 BYTE rgbRed; 17 BYTE rgbReserved; 18 } RGBQUAD; 19 20 #pragma pack (2) /*指定按字節(jié)對(duì)齊*/ 21 typedef struct tagBITMAPFILEHEADER { 22 WORD bfType; 23 DWORD bfSize; 24 WORD bfReserved1; 25 WORD bfReserved2; 26 DWORD bfOffBits; 27 } BITMAPFILEHEADER; 28 29 //恢復(fù)對(duì)齊狀態(tài) 30 typedef struct tagBITMAPINFOHEADER{ 31 DWORD biSize; 32 LONG biWidth; 33 LONG biHeight; 34 WORD biPlanes; 35 WORD biBitCount; 36 DWORD biCompression; 37 DWORD biSizeImage; 38 LONG biXPelsPerMeter; 39 LONG biYPelsPerMeter; 40 DWORD biClrUsed; 41 DWORD biClrImportant; 42 } BITMAPINFOHEADER; 43 44 unsigned char *pTempBmpBuf; //讀入圖像數(shù)據(jù)的指針 45 46 unsigned char *pBmpBuf; //讀入圖像數(shù)據(jù)的指針 47 48 49 int bmpWidth; //圖像的寬 50 int bmpHeight; //圖像的高 51 RGBQUAD *pColorTable; //顏色表指針 52 int biBitCount; //圖像類型,每像素位數(shù) 53 54 bool readBmp(char *bmpName) 55 { 56 //二進(jìn)制讀方式打開指定的圖像文件 57 58 FILE *fp=fopen(bmpName,"rb"); 59 if(fp==0) return 0; 60 61 62 //跳過(guò)位圖文件頭結(jié)構(gòu)BITMAPFILEHEADER 63 fseek(fp, sizeof(BITMAPFILEHEADER),0); 64 65 //定義位圖信息頭結(jié)構(gòu)變量,讀取位圖信息頭進(jìn)內(nèi)存,存放在變量head中 66 BITMAPINFOHEADER head; 67 fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); 68 69 //獲取圖像寬、高、每像素所占位數(shù)等信息 70 bmpWidth = head.biWidth; 71 bmpHeight = head.biHeight; 72 biBitCount = head.biBitCount; 73 74 75 //定義變量,計(jì)算圖像每行像素所占的字節(jié)數(shù)(必須是的倍數(shù)) 76 int lineByte=(bmpWidth * biBitCount/8+3)/4*4; 77 78 //灰度圖像有顏色表,且顏色表表項(xiàng)為 79 if(biBitCount==8){ 80 //申請(qǐng)顏色表所需要的空間,讀顏色表進(jìn)內(nèi)存 81 pColorTable=new RGBQUAD[256]; 82 fread(pColorTable,sizeof(RGBQUAD),256,fp); 83 } 84 85 86 //申請(qǐng)位圖數(shù)據(jù)所需要的空間,讀位圖數(shù)據(jù)進(jìn)內(nèi)存 87 pTempBmpBuf=new unsigned char[lineByte * bmpHeight]; 88 89 pBmpBuf=new unsigned char[lineByte * bmpHeight]; 90 fread(pTempBmpBuf,1,lineByte * bmpHeight,fp); 91 fseek(fp, 1078,0); 92 fread(pBmpBuf,1,lineByte * bmpHeight,fp); 93 94 //關(guān)閉文件 95 fclose(fp); 96 return 1; 97 } 98 99 bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,int biBitCount, RGBQUAD *pColorTable) 100 { 101 102 if(!imgBuf) 103 return 0; 104 105 //顏色表大小,以字節(jié)為單位,灰度圖像顏色表為字節(jié),彩色圖像顏色表大小為 106 int colorTablesize=0; 107 if(biBitCount==8) 108 colorTablesize=1024; 109 110 //待存儲(chǔ)圖像數(shù)據(jù)每行字節(jié)數(shù)為的倍數(shù) 111 int lineByte=(width * biBitCount/8+3)/4*4; 112 113 //以二進(jìn)制寫的方式打開文件 114 FILE *fp=fopen(bmpName,"wb"); 115 if(fp==0) return 0; 116 117 //申請(qǐng)位圖文件頭結(jié)構(gòu)變量,填寫文件頭信息 118 BITMAPFILEHEADER fileHead; 119 fileHead.bfType = 0x4D42;//bmp類型 120 121 //bfSize是圖像文件個(gè)組成部分之和 122 fileHead.bfSize= sizeof(BITMAPFILEHEADER) 123 + sizeof(BITMAPINFOHEADER) 124 + colorTablesize + lineByte*height; 125 126 fileHead.bfReserved1 = 0; 127 fileHead.bfReserved2 = 0; 128 129 //bfOffBits是圖像文件前個(gè)部分所需空間之和 130 fileHead.bfOffBits=54+colorTablesize; 131 132 //寫文件頭進(jìn)文件 133 fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp); 134 135 //申請(qǐng)位圖信息頭結(jié)構(gòu)變量,填寫信息頭信息 136 BITMAPINFOHEADER head; 137 head.biBitCount=biBitCount; 138 head.biClrImportant=0; 139 head.biClrUsed=0; 140 head.biCompression=0; 141 head.biHeight=height; 142 head.biPlanes=1; 143 head.biSize=40; 144 head.biSizeImage=lineByte*height; 145 head.biWidth=width; 146 head.biXPelsPerMeter=0; 147 head.biYPelsPerMeter=0; 148 149 //寫位圖信息頭進(jìn)內(nèi)存 150 fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp); 151 152 //如果灰度圖像,有顏色表,寫入文件 153 if(biBitCount==8) 154 fwrite(pColorTable, sizeof(RGBQUAD),256, fp); 155 156 //寫位圖數(shù)據(jù)進(jìn)文件 157 fwrite(imgBuf, height*lineByte, 1, fp); 158 159 //關(guān)閉文件 160 fclose(fp); 161 return 1; 162 } 163 164 int _tmain(int argc, _TCHAR* argv[]) 165 { 166 //讀入指定BMP文件進(jìn)內(nèi)存 167 char readPath[]="guass_test.bmp"; 168 readBmp(readPath); 169 //輸出圖像的信息 170 printf("width=%d,height=%d,biBitCount=%d\n", 171 bmpWidth,bmpHeight,biBitCount); 172 173 //每行字節(jié)數(shù) 174 int lineByte=(bmpWidth*biBitCount/8+3)/4*4; 175 //定義最終寫入的數(shù)據(jù)體 176 //pBmpBuf=new unsigned char[lineByte * bmpHeight]; 177 //循環(huán)變量,圖像的坐標(biāo) 178 int y,x; 179 180 //循環(huán)變量,針對(duì)彩色圖像,遍歷每像素的三個(gè)分量 181 int k; 182 //單精度變量暫存計(jì)算后的灰度值(針對(duì)灰度圖像) 183 float TempNum; 184 //指向TempBmpbuf的指針 185 unsigned char *TemPtr; 186 //指向BmpBuf的指針 187 unsigned char *Ptr; 188 //定義*3的模板(拉普拉斯) 189 float CoefArray[9]={1.0f,2.0f,1.0f,2.0f,4.0f,2.0f,1.0f,2.0f,1.0f}; 190 //定義模板前乘的系數(shù)(拉普拉斯) 191 float coef=(float)(1.0/16.0);; 192 193 //lapulas濾波 194 if(biBitCount==8){//對(duì)于灰度圖像 195 for(y=1;y<bmpHeight-1;y++){ 196 for(x=0;x<bmpWidth-1;x++){ 197 198 TemPtr=pTempBmpBuf+y*lineByte+x; 199 Ptr=pBmpBuf+y*lineByte+x; 200 201 TempNum=(float)((unsigned char)*(TemPtr+lineByte-1))*CoefArray[0]; 202 TempNum+=(float)((unsigned char)*(TemPtr+lineByte))*CoefArray[1]; 203 TempNum+=(float)((unsigned char)*(TemPtr+lineByte+1))*CoefArray[2]; 204 TempNum+=(float)((unsigned char)*(TemPtr-1))*CoefArray[3]; 205 TempNum+=(float)((unsigned char)*TemPtr)*CoefArray[4]; 206 TempNum+=(float)((unsigned char)*(TemPtr+1))*CoefArray[5]; 207 TempNum+=(float)((unsigned char)*(TemPtr-lineByte-1))*CoefArray[6]; 208 TempNum+=(float)((unsigned char)*(TemPtr-lineByte))*CoefArray[7]; 209 TempNum+=(float)((unsigned char)*(TemPtr-lineByte+1))*CoefArray[8]; 210 211 TempNum*=coef; 212 213 if(TempNum>255.0) *Ptr =(BYTE)255; 214 else if(TempNum<0.0) 215 *Ptr =(unsigned char)fabs(TempNum); 216 //用到了fabs函數(shù),需要添加math.h頭文件 217 else *Ptr=(char)TempNum; 218 } 219 } 220 } 221 222 else if(biBitCount==24){//彩色圖像 223 for(y=0;y<bmpHeight/2;y++){ 224 for(x=0;x<bmpWidth/2;x++){ 225 for(k=0;k<3;k++)//每像素RGB三個(gè)分量分別置才變成黑色 226 *(pBmpBuf+y*lineByte+x*3+k)=0; 227 } 228 } 229 } 230 //將圖像數(shù)據(jù)存盤 231 char writePath[]="gauss_result.BMP"; 232 saveBmp(writePath, pBmpBuf, bmpWidth, 233 bmpHeight, biBitCount, pColorTable); 234 //清除緩沖區(qū),pBmpBuf和pColorTable是全局變量,在文件讀入時(shí)申請(qǐng)的空間 235 delete []pBmpBuf; 236 delete []pTempBmpBuf; 237 if(biBitCount==8) 238 delete []pColorTable; 239 return 0; 240 }高斯濾波處理之后:?????????????????????????????????????????????????????????????????? 高斯濾波處理之前:
???
總結(jié)
以上是生活随笔為你收集整理的图像滤波之高斯滤波介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图像处理常用边缘检测算子总结
- 下一篇: 图像处理之中值滤波介绍及C实现