中值滤波是一种典型的非线性滤波技术,在一定条件下可以克服线性滤波器(如均值滤波)带来的图像细节模糊。
优点:消除杂散噪声点而不会或较小程度地造成边缘模糊。
缺点:对于图像中含有较多点、线、尖角细节的,不适宜采用中值滤波。
基本思想:将模板(如方形、线形、十字形、菱形等)中的像素值从小到大排序,将中值代替模板中间的或者指定位置的像素值。
下面给出模板为3x3大小方形的中值滤波C++源代码:
/**************中值滤波************** //Luma for( y = 1; y < height-1; y++ ) { pBgf += stride; for( x = 1; x < width-1; x++ ) { //Insertion-Sort(A):3x3 Pel A[9]; A[0]=(pBgf-stride)[x-1]; A[1]=(pBgf-stride)[x]; A[2]=(pBgf-stride)[x+1]; A[3] = pBgf[x-1]; A[4] = pBgf[x]; A[5] = pBgf[x+1]; A[6]=(pBgf+stride)[x-1]; A[7]=(pBgf+stride)[x]; A[8]=(pBgf+stride)[x+1]; for(int j=1; j<9; j++) { Pel key=A[j]; int i=j-1; while( i>0 && A[i]>key ) { A[i+1]=A[i]; i=i-1; } A[i+1]=key; } pBgf[x] = A[5];//取中值代替模板中心位置的像素值 } } height >>= 1; width >>= 1; stride >>= 1; //Cb pBgf = pcPicYuvBgf->getCbAddr(); for( y = 1; y < height-1; y++ ) { pBgf += stride; for( x = 1; x < width-1; x++ ) { //Insertion-Sort(A):3x3 Pel A[9]; A[0]=(pBgf-stride)[x-1]; A[1]=(pBgf-stride)[x]; A[2]=(pBgf-stride)[x+1]; A[3] = pBgf[x-1]; A[4] = pBgf[x]; A[5] = pBgf[x+1]; A[6]=(pBgf+stride)[x-1]; A[7]=(pBgf+stride)[x]; A[8]=(pBgf+stride)[x+1]; for(int j=1; j<9; j++) { Pel key=A[j]; int i=j-1; while( i>0 && A[i]>key ) { A[i+1]=A[i]; i=i-1; } A[i+1]=key; } pBgf[x] = A[5];//取中值代替模板中心位置的像素值 } } //Cr pBgf = pcPicYuvBgf->getCrAddr(); for( y = 1; y < height-1; y++ ) { pBgf += stride; for( x = 1; x < width-1; x++ ) { //Insertion-Sort(A):3x3 Pel A[9]; A[0]=(pBgf-stride)[x-1]; A[1]=(pBgf-stride)[x]; A[2]=(pBgf-stride)[x+1]; A[3] = pBgf[x-1]; A[4] = pBgf[x]; A[5] = pBgf[x+1]; A[6]=(pBgf+stride)[x-1]; A[7]=(pBgf+stride)[x]; A[8]=(pBgf+stride)[x+1]; for(int j=1; j<9; j++) { Pel key=A[j]; int i=j-1; while( i>0 && A[i]>key ) { A[i+1]=A[i]; i=i-1; } A[i+1]=key; } pBgf[x] = A[5];//取中值代替模板中心位置的像素值 } }