数字图像处理领域算法之高斯平滑
摘自:http://blog.csdn.net/v_july_v/article/details/6227072
算法描述:
在图像预处理中,对图像进行平滑,去除噪声,恢复原始图像是一个重要内容。本文设计了一个平滑尺度和模板大小均可以改变的高斯滤波器,用它对多幅加入各种噪声后的图像进行平滑,经过对各个结果图像的对比可知高斯滤波对服从正态分布的噪声去除效果比较好,并且相比各个不同参数,在平滑尺度为2,模板大小为7时效果最佳。
程序实现:
函数名称:Template:
参数:HDIB hDIB -图像的句柄
double *tem -指向模板的指针
int tem_w -模板的宽度
int tem_h -模板的高度
double xishu -模板的系数
功能:对图像进行模板操作
说明:为处理方便起见,模板的宽度和高度都应为奇数
HDIB Template(HDIB hDIB,double * tem ,int tem_w,int tem_h,double xishu)
{
//统计中间值
double sum;
//指向图像起始位置的指针
BYTE *lpDIB=(BYTE*)::GlobalLock((HGLOBAL) hDIB);
//指向象素起始位置的指针
BYTE *pScrBuff =(BYTE*)::FindDIBBits((char*)lpDIB);
//获取图像的颜色信息
int numColors=(int) ::DIBNumColors((char *)lpDIB);
//如果图像不是256色返回
if (numColors!=256)
{
//解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
//返回
return(hDIB);
}
//将指向图像象素起始位置的指针,赋值给指针变量
BYTE* oldbuf = pScrBuff;
//循环变量
int i,j,m,n;
int w, h, dw;
//获取图像的宽度
w = (int) ::DIBWidth((char *)lpDIB);
//获取图像的高度
h = (int) ::DIBHeight((char *)lpDIB);
//计算图像每行的字节数
dw = (w+3)/4*4;
//建立一个和原图像大小相同的25色灰度位图
HDIB newhDIB=NewDIB(w,h,8);
//指向新的位图的指针
BYTE *newlpDIB=(BYTE*)::GlobalLock((HGLOBAL) newhDIB);
//指向新的位图的象素起始位置的指针
BYTE *destBuf = (BYTE*)FindDIBBits((char *)newlpDIB);
//将指向新图像象素起始位置的指针,赋值给指针变量
BYTE *newbuf=destBuf;
//对图像进行扫描
//行
for(i=0;i<h;i++)
{
//列
for(j=0;j<w;j++)
{
//为统计变量赋初始值
sum=0;
//对于图像的4个边框的象素保持原灰度不变
if( j<((tem_w-1)/2) || j>(w-(tem_w+1)/2) || i<((tem_h-1)/2) || i>(h-
(tem_h+1)/2) )
*(newbuf+i*dw+j)=*(oldbuf+i*dw+j);
//对于其他的象素进行模板操作
else
{
//将点(i,j)点作为模板的中心
for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++)
{
for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++)
//将以点(i,j)为中心,与模板大小相同的范围内的象素与模板对用位置的
系数
//进行相乘并线形叠加
sum+=*(oldbuf+m*dw+n)* tem[(m-i+((tem_h-1)/2))*tem_w+n-j+
((tem_w-1)/2)];
}
//将结果乘上总的模板系数
sum=(int)sum*xishu;
//计算绝对值
sum = fabs(sum);
//如果小于0,强制赋值为0
if(sum<0)
sum=0;
//如果大于255,强制赋值为255
if(sum>255)
sum=255;
//将计算的结果放到新的位图的相应位置
*(newbuf+i*dw+j)=sum;
}
}
}
//解除锁定
::GlobalUnlock((HGLOBAL)hDIB);
//返回新的位图的句柄
return(newhDIB);
}
变换效果(图像右边部分即为某一算法的变换效果,下同):