图像增强-选择式掩膜平滑
邻域平均法和加权平均法在消除噪声的同时,都不可避免地带来平均化的缺憾,致使尖锐变化的边缘或线条变得模糊。考虑图像中目标物体和背景一般都具有不同的统计特性,即不同的均值和方差,为保留一定的边缘信息,可采用选择式掩膜平滑滤波,这样可以得到较好的图像细节。这种方法以尽量不模糊边缘轮廓为目的。
1.基本原理
选择式掩膜平滑方法取5×5的模板窗口,以中心像素为基准点,制作4个五边形、4个六边形、一个边长为3的正方形共9个形状的屏幕窗口,分别计算每个窗口内的平均值及方差。由于含有尖锐边缘的区域,方差必定比平缓区域大,因此采用方差最小的屏蔽窗口进行平均化。这种方法在完成滤波操作的同时,又不破坏区域边界的细节。这种采用9种形状的屏蔽窗口,分别计算各窗口内的灰度值方差,并采用方差最小的屏蔽窗口进行平均化的方法,也称为自适应平滑方法。下图为9种屏蔽窗口的模板
均值的计算公式为:
计算方差的公式为:
式中,k=1,2,3,4·····,N N为各模板对应的像素个数。
算法实现:
View Code
1 void CImgEnhance::ChooseMask() 2 { 3 if(m_nBitCount!=8) 4 { 5 AfxMessageBox("只能处理8位灰度图像!"); 6 return ; 7 } 8 int n,pixel[9],nmin; 9 float mean[9],var[9],bmin; 10 11 if(m_pImgDataOut!=NULL) 12 { 13 delete []m_pImgDataOut; 14 m_pImgDataOut=NULL; 15 } 16 //创建要复制的图像区域 17 m_nBitCountOut=m_nBitCount; 18 int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4; 19 if (!m_pImgDataOut) 20 { 21 m_pImgDataOut=new unsigned char[lineByteOut*m_imgHeight]; 22 } 23 24 memset(m_pImgDataOut,255,lineByteOut * m_imgHeight); 25 for(int j=2;j<=m_imgHeight-3;j++) 26 for(int i=2;i<=m_imgWidth-3;i++) 27 { 28 //求9种近邻区域的均值及其方差 29 //第1近邻区域 30 pixel[0]=m_pImgData[(j-1)*lineByteOut+(i-1)]; 31 pixel[1]=m_pImgData[(j-1)*lineByteOut+i]; 32 pixel[2]=m_pImgData[(j-1)*lineByteOut+(i+1)]; 33 pixel[3]=m_pImgData[j*lineByteOut+(i-1)]; 34 pixel[4]=m_pImgData[j*lineByteOut+i]; 35 pixel[5]=m_pImgData[j*lineByteOut+(i+1)]; 36 pixel[6]=m_pImgData[(j+1)*lineByteOut+(i-1)]; 37 pixel[7]=m_pImgData[(j+1)*lineByteOut+i]; 38 pixel[8]=m_pImgData[(j+1)*lineByteOut+(i+1)]; 39 mean[0]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6]+pixel[7]+pixel[8])/9; 40 var[0]=0; 41 for(n=0;n<=8;n++) 42 var[0]+=pixel[n]*pixel[n]-mean[0]*mean[0]; 43 //第2近邻区域 44 pixel[0]=m_pImgData[(j-2)*lineByteOut+(i-1)]; 45 pixel[1]=m_pImgData[(j-2)*lineByteOut+i]; 46 pixel[2]=m_pImgData[(j-2)*lineByteOut+(i+1)]; 47 pixel[3]=m_pImgData[(j-1)*lineByteOut+(i-1)]; 48 pixel[4]=m_pImgData[(j-1)*lineByteOut+i]; 49 pixel[5]=m_pImgData[(j-1)*lineByteOut+(i+1)]; 50 pixel[6]=m_pImgData[j*lineByteOut+i]; 51 mean[1]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 52 var[1]=0; 53 for(n=0;n<=6;n++) 54 var[1]+=pixel[n]*pixel[n]-mean[1]*mean[1]; 55 //第3近邻区域 56 pixel[0]=m_pImgData[(j-1)*lineByteOut+(i-2)]; 57 pixel[1]=m_pImgData[(j-1)*lineByteOut+(i-1)]; 58 pixel[2]=m_pImgData[j*lineByteOut+(i-2)]; 59 pixel[3]=m_pImgData[j*lineByteOut+(i-1)]; 60 pixel[4]=m_pImgData[j*lineByteOut+i]; 61 pixel[5]=m_pImgData[(j+1)*lineByteOut+(i-2)]; 62 pixel[6]=m_pImgData[(j+1)*lineByteOut+(i-1)]; 63 mean[2]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 64 var[2]=0; 65 for(n=0;n<=6;n++) 66 var[2]+=pixel[n]*pixel[n]-mean[2]*mean[2]; 67 //第4近邻区域 68 pixel[0]=m_pImgData[j*lineByteOut+i]; 69 pixel[1]=m_pImgData[(j+1)*lineByteOut+(i-1)]; 70 pixel[2]=m_pImgData[(j+1)*lineByteOut+i]; 71 pixel[3]=m_pImgData[(j+1)*lineByteOut+(i+1)]; 72 pixel[4]=m_pImgData[(j+2)*lineByteOut+(i-1)]; 73 pixel[5]=m_pImgData[(j+2)*lineByteOut+i]; 74 pixel[6]=m_pImgData[(j+2)*lineByteOut+(i+1)]; 75 mean[3]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 76 var[3]=0; 77 for(n=0;n<=6;n++) 78 var[3]+=pixel[n]*pixel[n]-mean[3]*mean[3]; 79 //第5近邻区域 80 pixel[0]=m_pImgData[(j-1)*lineByteOut+(i+1)]; 81 pixel[1]=m_pImgData[(j-1)*lineByteOut+(i+2)]; 82 pixel[2]=m_pImgData[j*lineByteOut+i]; 83 pixel[3]=m_pImgData[j*lineByteOut+(i+1)]; 84 pixel[4]=m_pImgData[j*lineByteOut+(i+2)]; 85 pixel[5]=m_pImgData[(j+1)*lineByteOut+(i+1)]; 86 pixel[6]=m_pImgData[(j+1)*lineByteOut+(i+2)]; 87 mean[4]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 88 var[4]=0; 89 for(n=0;n<=6;n++) 90 var[4]+=pixel[n]*pixel[n]-mean[4]*mean[4]; 91 //第6近邻区域 92 pixel[0]=m_pImgData[(j-2)*lineByteOut+(i+1)]; 93 pixel[1]=m_pImgData[(j-2)*lineByteOut+(i+2)]; 94 pixel[2]=m_pImgData[(j-1)*lineByteOut+i]; 95 pixel[3]=m_pImgData[(j-1)*lineByteOut+(i+1)]; 96 pixel[4]=m_pImgData[(j-1)*lineByteOut+(i+2)]; 97 pixel[5]=m_pImgData[j*lineByteOut+i]; 98 pixel[6]=m_pImgData[j*lineByteOut+(i+1)]; 99 mean[5]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 100 var[5]=0; 101 for(n=0;n<=6;n++) 102 var[5]+=pixel[n]*pixel[n]-mean[5]*mean[5]; 103 //第7近邻区域 104 pixel[0]=m_pImgData[(j-2)*lineByteOut+(i-2)]; 105 pixel[1]=m_pImgData[(j-2)*lineByteOut+(i-1)]; 106 pixel[2]=m_pImgData[(j-1)*lineByteOut+(i-2)]; 107 pixel[3]=m_pImgData[(j-1)*lineByteOut+(i-1)]; 108 pixel[4]=m_pImgData[(j-1)*lineByteOut+i]; 109 pixel[5]=m_pImgData[j*lineByteOut+(i-1)]; 110 pixel[6]=m_pImgData[j*lineByteOut+i]; 111 mean[6]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 112 var[6]=0; 113 for(n=0;n<=6;n++) 114 var[6]+=pixel[n]*pixel[n]-mean[6]*mean[6]; 115 //第8近邻区域 116 pixel[0]=m_pImgData[j*lineByteOut+(i-1)]; 117 pixel[1]=m_pImgData[j*lineByteOut+i]; 118 pixel[2]=m_pImgData[(j+1)*lineByteOut+(i-2)]; 119 pixel[3]=m_pImgData[(j+1)*lineByteOut+(i-1)]; 120 pixel[4]=m_pImgData[(j+1)*lineByteOut+i]; 121 pixel[5]=m_pImgData[(j+2)*lineByteOut+(i-2)]; 122 pixel[6]=m_pImgData[(j+2)*lineByteOut+(i-1)]; 123 mean[7]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 124 var[7]=0; 125 for(n=0;n<=6;n++) 126 var[7]+=pixel[n]*pixel[n]-mean[7]*mean[7]; 127 //第9近邻区域 128 pixel[0]=m_pImgData[j*lineByteOut+i]; 129 pixel[1]=m_pImgData[j*lineByteOut+(i+1)]; 130 pixel[2]=m_pImgData[(j+1)*lineByteOut+i]; 131 pixel[3]=m_pImgData[(j+1)*lineByteOut+(i+1)]; 132 pixel[4]=m_pImgData[(j+1)*lineByteOut+(i+2)]; 133 pixel[5]=m_pImgData[(j+2)*lineByteOut+(i+1)]; 134 pixel[6]=m_pImgData[(j+2)*lineByteOut+(i+2)]; 135 mean[8]=(float)(pixel[0]+pixel[1]+pixel[2]+pixel[3]+pixel[4]+pixel[5]+pixel[6])/7; 136 var[8]=0; 137 for(n=0;n<=6;n++) 138 var[8]+=pixel[n]*pixel[n]-mean[8]*mean[8]; 139 //求方差最小的近邻区域nmin 140 bmin=var[0]; 141 nmin=0; 142 for(n=0;n<=8;n++) 143 { 144 if(bmin>var[n]) 145 { 146 bmin=var[n]; 147 nmin=n; 148 } 149 //把nmin的值四舍五入后作为显示图像的值 150 m_pImgDataOut[j*lineByteOut+i]=(int)(mean[nmin]+0.5); 151 } 152 } 153 }