实验:
1.向图像添加椒盐噪声;
2.利用2个3×3模板的均值滤波器对受噪声干扰的图像进行平滑处。
主要函数:
void SaltNoise(IplImage*src,IplImage*dst);//产生椒盐噪声
void FilterAverage1(IplImage*src,IplImage*dst);//3*3均值滤波
void FilterAverage2(IplImage*src,IplImage*dst);//3*3均值滤波
void laplace(IplImage*src,IplImage*dst);//拉普拉斯算法图像锐化
void GaussianNoise(IplImage*src,IplImage*dst,int mu,int sigma);//高斯噪声
void FilterMid(IplImage*src,IplImage*dst);//中值滤波
伪代码:
void SaltNoise(IplImage*src,IplImage*dst)
{
for(int i=0;i<传入图像的高度;i++)
for(int j=0 ;j<传入图像的宽度;j++)
{
Int grayvalue = (i,j)像素点的像素值;
Int value=随机数;
Uchar *ptr指向图像矩阵当前坐标指针;
If(value>31500)
当前坐标值=0;即为黑色
Else
原像素点值保持不变;
}
}
void FilterAverage1(IplImage*src,IplImage*dst);//3*3均值滤波
{
for(int i=0;i<传入图像的高度;i++)
for(int j=0 ;j<传入图像的宽度;j++)
{
If((i,j)所在位置在图像的坐标范围内)
{
Int value= 1/9 *滤波器
即当前等于当前像素点与其八邻域像素点乘以相应系数之和的十六分之一;
}
Uchar *ptr 指向当前像素点;
*ptr=3*3模板得到的值;
}
}
void FilterAverage2(IplImage*src,IplImage*dst);//3*3均值滤波
{
for(int i=0;i<传入图像的高度;i++)
for(int j=0 ;j<传入图像的宽度;j++)
{
If((i,j)所在位置在图像的坐标范围内)
{
Int value= 1/16 *滤波器
即当前等于当前像素点与其八邻域像素点乘以相应系数之和的十六分之一;
}
Uchar *ptr 指向当前像素点;
*ptr=3*3模板得到的值;
}
}
源代码:
#include
#include
#include
#include
#include
using namespace std;
void SaltNoise(IplImage*src,IplImage*dst);//产生椒盐噪声
void FilterAverage1(IplImage*src,IplImage*dst);//3*3均值滤波
void FilterAverage2(IplImage*src,IplImage*dst);//3*3均值滤波
void laplace(IplImage*src,IplImage*dst);//拉普拉斯算法图像锐化
void GaussianNoise(IplImage*src,IplImage*dst,int mu,int sigma);//高斯噪声
void FilterMid(IplImage*src,IplImage*dst);//中值滤波
void main ()
{
IplImage* image=cvLoadImage("grayLena.bmp",-1);
IplImage* Salt_image=0;
IplImage* Aver_image1=0;
IplImage* Aver_image2=0;
IplImage *Gauss_image=0;
IplImage *mid_image=0;
IplImage *laplace_image=0;
Salt_image=cvCreateImage(cvSize(image->width,image->height),8,1);//IplImage* cvCreateImage( CvSize size, int depth, int channels );
Gauss_image=cvCreateImage(cvSize(image->width,image->height),8,1);
Aver_image1=cvCreateImage(cvSize(image->width,image->height),8,1);
Aver_image2=cvCreateImage(cvSize(image->width,image->height),8,1);
mid_image=cvCreateImage(cvSize(image->width,image->height),8,1);
laplace_image=cvCreateImage(cvSize(image->width,image->height),8,1);
SaltNoise(image,Salt_image);
GaussianNoise(image,Gauss_image,5,20);
FilterAverage1(Gauss_image,Aver_image1);
FilterAverage2(Gauss_image,Aver_image2);
FilterMid(Gauss_image,mid_image);
laplace(Aver_image2,laplace_image);
cvNamedWindow("image",CV_WINDOW_AUTOSIZE);
cvNamedWindow("Aver_image1",CV_WINDOW_AUTOSIZE);
cvNamedWindow("Aver_image2",CV_WINDOW_AUTOSIZE);
cvNamedWindow("Gauss_image",CV_WINDOW_AUTOSIZE);
cvNamedWindow("Salt_image",CV_WINDOW_AUTOSIZE);
cvNamedWindow("mid_image",CV_WINDOW_AUTOSIZE);
cvNamedWindow("laplace_image",CV_WINDOW_AUTOSIZE);
cvShowImage("image",image);
cvShowImage("Gauss_image",Gauss_image);
cvShowImage("Aver_image1",Aver_image1);
cvShowImage("Aver_image2",Aver_image2);
cvShowImage("Salt_image",Salt_image);
cvShowImage("mid_image",mid_image);
cvShowImage("laplace_image",laplace_image);
cvSaveImage("Salt_Lena.bmp",Salt_image);
cvSaveImage("mid_Lena.bmp",mid_image);
cvWaitKey(0);//cvWaitKey()函数的功能是不断刷新图像,频率时间为delay,单位为ms。返回值为当前键盘按键值。
cvDestroyWindow("image");
cvDestroyWindow("Salt_image");
cvReleaseImage(&image);
cvReleaseImage(&Salt_image);
}
void SaltNoise(IplImage*src,IplImage*dst)
{
for (int i=0;iheight;i++)
for(int j=0;jwidth;j++)
{
int grayvalue=(int)CV_IMAGE_ELEM(src,uchar,i,j);//假设灰度图像image,存取其i行j列的象素可以这样:CV_IMAGE_ELEM(image, uchar,y, x)
int value=rand();
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
if(value>31500)
{
//cout< d(mu, sigma);
for (int i=0;iheight;i++)
for(int j=0;jwidth;j++)
{
int grayvalue=(int)CV_IMAGE_ELEM(src,uchar,i,j);
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
int p=d(gen)+grayvalue;
p=p>255? 255:p;
p=p<0? 0:p;
*ptr=p;
}
}
void FilterAverage1(IplImage*src,IplImage*dst)//均值滤波函数,利用3*3模板
{ // 1 2 1
for(int i=1;iheight;i++) //1/16* 2 4 2
for(int j=1;jwidth;j++) // 1 2 1
if((i-1)>=0&&j-1>=0&&i+1height&&j+1width)
{ //
int value=(int)(4*(int)CV_IMAGE_ELEM(src,uchar,i,j)+(int) CV_IMAGE_ELEM(src,uchar,i-1,j-1)+(int)CV_IMAGE_ELEM(src,uchar,i+1,j+1)
+2*(int)CV_IMAGE_ELEM(src,uchar,i-1,j)+2*(int)CV_IMAGE_ELEM(src,uchar,i+1,j)+2*(int)CV_IMAGE_ELEM(src,uchar,i,j-1)+2*(int)CV_IMAGE_ELEM(src,uchar,i,j+1)+
(int)CV_IMAGE_ELEM(src,uchar,i-1,j+1)+(int)CV_IMAGE_ELEM(src,uchar,i+1,j-1))/16;
//均值滤波函数,
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=value;
}
else
{
int grayvalue=(int)CV_IMAGE_ELEM(src,uchar,i,j);
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=grayvalue;
}
}
void FilterAverage2(IplImage*src,IplImage*dst)//均值滤波函数,利用3*3模板
{ // 1 1 1
for(int i=1;iheight;i++) //1/9* 1 1 1
for(int j=1;jwidth;j++)
if((i-1)>=0&&j-1>=0&&i+1height&&j+1width)// 1 1 1
{ //
int value=(int)((int)CV_IMAGE_ELEM(src,uchar,i,j)+(int)CV_IMAGE_ELEM(src,uchar,i-1,j-1)+(int)CV_IMAGE_ELEM(src,uchar,i+1,j+1)
+(int)CV_IMAGE_ELEM(src,uchar,i-1,j)+(int)CV_IMAGE_ELEM(src,uchar,i+1,j)+(int)CV_IMAGE_ELEM(src,uchar,i,j-1)+(int)CV_IMAGE_ELEM(src,uchar,i,j+1)+
(int)CV_IMAGE_ELEM(src,uchar,i-1,j+1)+(int)CV_IMAGE_ELEM(src,uchar,i+1,j-1))/9;
//均值滤波函数,
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=value;
}
else
{
int grayvalue=(int)CV_IMAGE_ELEM(src,uchar,i,j);
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=grayvalue;
}
}
void FilterMid(IplImage*src,IplImage*dst)//在3*3模板空间找到中间值
{
for(int i=1;iheight;i++)
for(int j=1;jwidth;j++)
if((i-1)>=0&&j-1>=0&&i+1height&&j+1width)
{
int value[9],temp;
int midValue=(int)CV_IMAGE_ELEM(src,uchar,i-1,j-1);
value[0]=(int)CV_IMAGE_ELEM(src,uchar,i-1,j-1);
value[1]=(int)CV_IMAGE_ELEM(src,uchar,i-1,j);
value[2]=(int)CV_IMAGE_ELEM(src,uchar,i-1,j+1);
value[3]=(int)CV_IMAGE_ELEM(src,uchar,i,j-1);
value[4]=(int)CV_IMAGE_ELEM(src,uchar,i,j);
value[5]=(int)CV_IMAGE_ELEM(src,uchar,i,j+1);
value[6]=(int)CV_IMAGE_ELEM(src,uchar,i+1,j-1);
value[7]=(int)CV_IMAGE_ELEM(src,uchar,i+1,j);
value[8]=(int)CV_IMAGE_ELEM(src,uchar,i+1,j+1);
for(int m=0;m<8;m++)
{
temp=value[m];
for(int n=8;n>m;n--)
{
if(temp > value[n])
{
value[m] = value[n];
value[n] = temp;
temp =value[m];
}
}
}
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=value[4];
}
else
{
int grayvalue=(int)CV_IMAGE_ELEM(src,uchar,i,j);
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=grayvalue;
}
}
void laplace(IplImage*src,IplImage*dst)
{
for (int i=1;iheight;i++)
for(int j=1;jwidth;j++)
if((i-1)>=0&&j-1>=0&&i+1height&&j+1width)
{
int value=(5)*(int)CV_IMAGE_ELEM(src,uchar,i,j)-(int)CV_IMAGE_ELEM(src,uchar,i-1,j)-(int)CV_IMAGE_ELEM(src,uchar,i+1,j)-
(int)CV_IMAGE_ELEM(src,uchar,i,j-1)-(int)CV_IMAGE_ELEM(src,uchar,i,j+1);
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=value;
}
else
{
int grayvalue=(int)CV_IMAGE_ELEM(src,uchar,i,j);
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
*ptr=grayvalue;
}
for (int i=1;iheight;i++)
for(int j=1;jwidth;j++)
{
uchar*ptr=(uchar*)(dst->imageData+i*dst->width+j);
if ((int)CV_IMAGE_ELEM(dst,uchar,i,j)<=0)
{
*ptr=0;
}
}
}
调试分析:
图1 加入椒盐噪声
图二 第一种均值滤波
图三 第二种均值滤波