天天看點

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

  雙邊濾波(bilateral filter)是一種非線性濾波器,算法結合空間資訊(像素的坐标)和亮度相似性(像素值0-255)對圖像進行濾波處理,在平滑濾波的同時能大量保留圖像的邊緣和細節特征 。

積分,通用均值濾波和高斯濾波,f(x)為輸入圖像,h(x)為輸出圖像 :

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

1/kd(x)為歸一化參數,保證絕對平滑的位置灰階值不變。

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images
圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

積分下:空間資訊(像素的坐标):

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

積分下:亮度相似性(像素值0-255):

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

權重系數W( i, j, k, l)對應積分的表示:

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images
圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

對應的,離散求和,f(i,j)為輸入圖像,g(i,j)為輸出圖像 ,以輸入圖像(k,l)為中心的鄰域,求和範圍是模闆覆寫的範圍:

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

離散下:空間資訊(像素的坐标):

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

離散下:亮度相似性(像素值0-255):

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

權重系數W( i, j, k, l)=d( i, j, k, l) * r( i, j, k, l):

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

其中

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

為空域(像素的坐标)高斯函數的标準差,

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

為值域(像素值0-255)高斯函數的标準差。空域濾波系數由像素間的空間距離決定,距離越小,系數越大。值域濾波系數由像素間的相似度決定,像素值越接近,系數越大。

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

雙邊濾波效果圖(delta_d=3;//空間位置方差    delta_r=100;//亮度方差)

圖像處理 雙邊濾波器 Bilateral Filtering for Gray and Color Images

void CShowPicView::OnBilateralFilter() // 雙邊濾波

{

CShowPicDoc* pDoc = GetDocument();

CDC* pDC=GetDC();

// 字元串

CString str;

int x,y;

int i,j,k,l;

double W_ijkl, D_ijkl, R_ijkl;

double Sum_W_ijkl;

double delta_d=3,delta_r=100;//空間位置方差,亮度方差

unsigned char g[610][800]={0};//存放輸出圖像的像素值

double Sum_Data;

// 濾波器的高度

int iFilterH= 11;

// 濾波器的寬度

int iFilterW= 11;

// 中心元素的X坐标

int iFilterMX= 5;

// 中心元素的Y坐标

int iFilterMY= 5;

int lHeight=intHeight;//圖像的寬

int lWidth=intWidth;//圖像的寬

// 行(除去邊緣幾行)

for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++)

{

// 列(除去邊緣幾列)

for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++)

{

Sum_W_ijkl=0;//圖像中心位置移動,置零

Sum_Data=0;

for (k = i-5; k < iFilterH+i-5; k++)

{

for (l = j-5; l < iFilterW+j-5; l++)

{

D_ijkl = exp(-1 * (pow(k-i,2)+pow(l-j,2))/(2*delta_d*delta_d) );

R_ijkl = exp(-1 *  pow(Data[k][l]-Data[i][j],2)/(2*delta_r*delta_r) );

W_ijkl = D_ijkl*R_ijkl;

Sum_Data+=W_ijkl*Data[k][l];

Sum_W_ijkl += W_ijkl;//權重累加和

}

}

g[i][j]=Sum_Data/Sum_W_ijkl;

}

}

for(y = 0; y < intHeight-1; y++)

for(int x = 0; x < intWidth-1; x++)

pDC->SetPixel(x+1*intWidth+30,y,RGB(g[y][x],g[y][x],g[y][x])); //打點顯示圖像

}