图像处理及分析实验四.docx
《图像处理及分析实验四.docx》由会员分享,可在线阅读,更多相关《图像处理及分析实验四.docx(17页珍藏版)》请在冰豆网上搜索。
![图像处理及分析实验四.docx](https://file1.bdocx.com/fileroot1/2023-2/5/433109ca-d72d-443d-b805-12afda6eb7f2/433109ca-d72d-443d-b805-12afda6eb7f21.gif)
图像处理及分析实验四
西华数学与计算机学院上机实践报告
课程名称:
计算机图形学
年级:
2011
上机实践成绩:
指导教师:
罗晓辉
姓名:
徐千
上机实践名称:
图像增强
学号:
312011*********
上机实践日期:
2013.10.27
上机实践编号:
4
上机实践时间:
14:
00-18:
00
一、目的
理解图像平滑、中值滤波以及拉普拉斯锐化基本原理,掌握基本的生成图像平滑、中值滤波以及拉普拉斯锐化算法,并实现图像平滑、中值滤波以及拉普拉斯锐化的图片效果,利用C++实现图像平滑、中值滤波以及拉普拉斯锐化的图片效果功能并处理图片效果。
二、内容与设计思想
内容:
(1)了解图像平滑、中值滤波以及拉普拉斯锐化原理。
1、二维中值滤波平滑:
用中值算法把数字图像中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,这样来过滤噪声,实现平滑。
但是,这样产生出来的图像会有一定的模糊。
2、梯度算法锐化:
用微分的方法对图像处理,锐化因为平滑导致的模糊。
3、拉普拉斯模糊:
通过二阶微分像素变得跟周围4个像素一样。
4、去除拉普拉斯模糊:
将拉普拉斯模糊形式从原图像中去除。
(2)掌握基本的生成图像平滑、中值滤波以及拉普拉斯锐化算法
(3)利用C++分别实现生成图像平滑、中值滤波以及拉普拉斯锐化。
(4)利用该算法在屏幕上处理图片的效果。
设计思想:
图像平滑:
平滑后的像素灰度值即该像素周围九个点的灰度值分别乘以平滑模板对应元素,再求它们之和,再取平均值
步骤:
打开工作区,在图像处理实验算法下的CAView中EhanSmooth函数下编写程序
lpDIB指向源图像的指针
lpDIBBits指向源图像像素起始位置的指针
lWidth是图像宽度
lHeight是图像高度
inta[9]平滑模板元素数组
a[0]=1;a[1]=1;a[2]=1;
a[3]=1;a[4]=1;a[5]=1;
a[6]=1;a[7]=1;a[8]=1;
注意图象的第一行,最后一行,第一列,最后一列跳过不处理;
中值滤波:
滤波后的像素灰度值即该像素周围九个点的灰度值的中值
步骤:
打开工作区,在图像处理实验算法下的CAView中MedianFilter函数下编写程序
lpDIB指向源图像的指针
lpDIBBits指向源图像像素起始位置的指针
lWidth是图像宽度
lHeight是图像高度
注意图象的第一行,最后一行,第一列,最后一列跳过不处理;
拉普拉斯锐化:
每个像素灰度值即该像素周围九个点的灰度值分别乘以锐化模板对应元素,再求它们之和,再取平均值
步骤:
打开工作区,在图像处理实验算法下的CAView中LSharp函数下编写程序
lpDIB指向源图像的指针
lpDIBBits指向源图像像素起始位置的指针
lWidth是图像宽度
lHeight是图像高度
inta[9]锐化模板元素数组
a[0]=0;a[1]=-1;a[2]=0;
a[3]=-1;a[4]=5;a[5]=-1;
a[6]=0;a[7]=-1;a[8]=0;
注意图象的第一行,最后一行,第一列,最后一列跳过不处理;
(4)仿照原理,编写代码,分别用图像平滑、中值滤波以及拉普拉斯锐化处理图片。
(5)调试、编译、生成程序。
(6)处理图片。
三、使用环境
Microsoftvisualc++6.0
Windows7
四、核心代码及调试过程.(实验结果)
BOOLCAView:
:
EhanSmooth(LPBYTElpDIBBits,LONGlWidth,LONGlHeight)
{
/*说明:
lpDIBBits是指向图象数据起始点的指针
lWidth是图像宽度
lHeight是图像高度
*/
/**********以下为可能涉及的指针等***************************************/
LPBYTElpSrc;//像素指针
LONGlLineBytes;//每行字节数
lLineBytes=WIDTHBYTES(lWidth*8);
longi,j;//循环变量
inta[9];//平滑模板元素数组
a[0]=1;
a[1]=1;
a[2]=1;
a[3]=1;
a[4]=1;
a[5]=1;
a[6]=1;
a[7]=1;
a[8]=1;
/****************************请在下面编写图像平滑的算法*************/
double*tempt=newdouble[lWidth*lHeight];
int*b=newint[9];
intk;
doublesum,mean;
for(i=1;i{
for(j=1;j{
lpSrc=lpDIBBits+lLineBytes*i+j;
b[0]=*(lpDIBBits+lLineBytes*(i-1)+j-1);
b[1]=*(lpDIBBits+lLineBytes*(i-1)+j);
b[2]=*(lpDIBBits+lLineBytes*(i-1)+j+1);
b[3]=*(lpDIBBits+lLineBytes*i+j-1);
b[4]=*(lpDIBBits+lLineBytes*i+j);
b[5]=*(lpDIBBits+lLineBytes*i+j+1);
b[6]=*(lpDIBBits+lLineBytes*(i+1)+j-1);
b[7]=*(lpDIBBits+lLineBytes*(i+1)+j);
b[8]=*(lpDIBBits+lLineBytes*(i+1)+j+1);
sum=0;
mean=0;
for(k=0;k<9;k++)
{
sum=sum+a[k]*b[k];
mean=sum/9;
}
tempt[lWidth*i+j]=mean;
}
}
for(i=1;i{
for(j=1;j{
lpSrc=lpDIBBits+lLineBytes*i+j;
if(tempt[lWidth*i+j]>255)
{
*lpSrc=(unsignedchar)255;
}
else{*lpSrc=(unsignedchar)tempt[lWidth*i+j];}
}
}
returnTRUE;
}
voidCAView:
:
OnMedianFilter()
{
BackForUndo(GetDocument()->GetHDIB());
//获取文档
CADoc*pDoc=GetDocument();
//指向DIB的指针
LPSTRlpDIB;
//锁定DIB
lpDIB=(LPSTR):
:
GlobalLock((HGLOBAL)pDoc->GetHDIB());
//源图像的宽度和高度
LONGlWidth;
LONGlHeight;
lWidth=:
:
DIBWidth(lpDIB);/*获取图像的"宽度"(4的倍数)*/
lHeight=:
:
DIBHeight(lpDIB)/*获取图像的高度*/;
//指向DIB象素的指针
LPBYTElpDIBBits;
//找到源DIB图像象素起始位置
lpDIBBits=(LPBYTE):
:
FindDIBBits(lpDIB);
//创建新DIB
HDIBhNewDIB=NULL;
//更改光标形状
BeginWaitCursor();
//判断平滑是否成功
if(MedianFilter(lpDIBBits,lWidth,lHeight))
{
//设置脏标记
pDoc->SetModifiedFlag(TRUE);
//更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
//提示用户
MessageBox("分配内存失败!
");
}
//解除锁定
:
:
GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
//恢复光标
EndWaitCursor();
}
BOOLCAView:
:
MedianFilter(LPBYTElpDIBBits,LONGlWidth,LONGlHeight)
{
/*说明:
lpDIBBits是指向图象数据起始点的指针
lWidth是图像宽度
lHeight是图像高度
*/
/**********以下为可能涉及的指针等***************************************/
LPBYTElpSrc;//像素指针
LONGlLineBytes;//每行字节数
lLineBytes=WIDTHBYTES(lWidth*8);
longi,j;//循环变量
/****************************请在下面编写中值滤波的算法*************/
int*tempt=newint[lWidth*lHeight];
unsignedchar*b=newunsignedchar[9];
for(i=1;i{
for(j=1;j{
lpSrc=lpDIBBits+lLineBytes*i+j;
b[0]=*(lpDIBBits+lLineBytes*(i-1)+j-1);
b[1]=*(lpDIBBits+lLineBytes*(i-1)+j);
b[2]=*(lpDIBBits+lLineBytes*(i-1)+j+1);
b[3]=*(lpDIBBits+lLineBytes*i+j-1);
b[4]=*(lpDIBBits+lLineBytes*i+j);
b[5]=*(lpDIBBits+lLineBytes*i+j+1);
b[6]=*(lpDIBBits+lLineBytes*(i+1)+j-1);
b[7]=*(lpDIBBits+lLineBytes*(i+1)+j);
b[8]=*(lpDIBBits+lLineBytes*(i+1)+j+1);
tempt[lWidth*i+j]=GetMedianNum(b,9);
}
}
for(i=1;i{
for(j=1;j{
lpSrc=lpDIBBits+lLineBytes*i+j;
if(tempt[lWidth*i+j]>255)
{
*lpSrc=(unsignedchar)255;
}
else{*lpSrc=(unsignedchar)tempt[lWidth*i+j];}
}
}
returnTRUE;
}
unsignedcharCAView:
:
GetMedianNum(unsignedchar*b,intnum)
{
//找中值(冒泡法)
//循环变量
inti;
intj;
//中间变量
unsignedcharf;
//用冒泡法对数组进行排序(b[0]最小)
for(j=0;j{
for(i=0;i{
if(b[i]>b[i+1])
{
//互换
f=b[i];
b[i]=b[i+1];
b[i+1]=f;
}
}
}
//计算中值
if((num&1)>0)
{
//数组有奇数个元素,返回中间一个元素
f=b[(num+1)/2];
}
else
{
//数组有偶数个元素,返回中间两个元素平均值
f=(b[num/2]+b[num/2+1])/2;
}
//返回中值
returnf;
}
voidCAView:
:
OnEnhaLsharp()
{
BackForUndo(GetDocument()->GetHDIB());
//获取文档
CADoc*pDoc=GetDocument();
//指向DIB的指针
LPSTRlpDIB;
//锁定DIB
lpDIB=(LPSTR):
:
GlobalLock((HGLOBAL)pDoc->GetHDIB());
//源图像的宽度和高度
LONGlWidth;
LONGlHeight;
lWidth=:
:
DIBWidth(lpDIB);/*获取图像的"宽度"(4的倍数)*/
lHeight=:
:
DIBHeight(lpDIB)/*获取图像的高度*/;
//指向DIB象素的指针
LPBYTElpDIBBits;
//找到源DIB图像象素起始位置
lpDIBBits=(LPBYTE):
:
FindDIBBits(lpDIB);
//创建新DIB
HDIBhNewDIB=NULL;
//更改光标形状
BeginWaitCursor();
//判断锐化是否成功
if(LSharp(lpDIBBits,lWidth,lHeight))
{
//设置脏标记
pDoc->SetModifiedFlag(TRUE);
//更新视图
pDoc->UpdateAllViews(NULL);
}
else
{
//提示用户
MessageBox("分配内存失败!
");
}
//解除锁定
:
:
GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
//恢复光标
EndWaitCursor();
}
BOOLCAView:
:
LSharp(LPBYTElpDIBBits,LONGlWidth,LONGlHeight)
{
/*说明:
lpDIBBits是指向图象数据起始点的指针
lWidth是图像宽度
lHeight是图像高度
/**********以下为可能涉及的指针等***************************************/
LPBYTElpSrc;//像素指针
LONGlLineBytes;//每行字节数
lLineBytes=WIDTHBYTES(lWidth*8);
longi,j;//循环变量
inta[9];//锐化模板元素数组
a[0]=0;
a[1]=-1;
a[2]=0;
a[3]=-1;
a[4]=5;
a[5]=-1;
a[6]=0;
a[7]=-1;
a[8]=0;
/****************************请在下面编写图像锐化的算法*************/
double*tempt=newdouble[lWidth*lHeight];
int*b=newint[9];
intk;
doublesum;
for(i=1;i{
for(j=1;j{
lpSrc=lpDIBBits+lLineBytes*i+j;
b[0]=*(lpDIBBits+lLineBytes*(i-1)+j-1);
b[1]=*(lpDIBBits+lLineBytes*(i-1)+j);
b[2]=*(lpDIBBits+lLineBytes*(i-1)+j+1);
b[3]=*(lpDIBBits+lLineBytes*i+j-1);
b[4]=*(lpDIBBits+lLineBytes*i+j);
b[5]=*(lpDIBBits+lLineBytes*i+j+1);
b[6]=*(lpDIBBits+lLineBytes*(i+1)+j-1);
b[7]=*(lpDIBBits+lLineBytes*(i+1)+j);
b[8]=*(lpDIBBits+lLineBytes*(i+1)+j+1);
sum=0;
for(k=0;k<9;k++)
{
sum=sum+a[k]*b[k];
}
tempt[lWidth*i+j]=sum;
}
}
for(i=1;i{
for(j=1;j{
lpSrc=lpDIBBits+lLineBytes*i+j;
if(tempt[lWidth*i+j]>255)
{
*lpSrc=(unsignedchar)255;
}
else{*lpSrc=(unsignedchar)tempt[lWidth*i+j];}
}
}
returnTRUE;
}运行结果如下:
五、总结
基本了解了图像平滑、中值滤波以及拉普拉斯锐化的要点:
对于在图片处理即平滑、滤波及锐化方面上有很重要的作用。
掌握基本的图像平滑、中值滤波以及拉普拉斯锐化,并实现图像平滑、中值滤波以及拉普拉斯锐化的处理图片效果。
在这次试验中,遇到了很多的难点,对自己的编程能力还有待提高。
六、附录