DSP实验四图像平滑实验.docx
《DSP实验四图像平滑实验.docx》由会员分享,可在线阅读,更多相关《DSP实验四图像平滑实验.docx(11页珍藏版)》请在冰豆网上搜索。
DSP实验四图像平滑实验
实验四:
图像平滑实验
一、实验目的
1.培养学生理解图像平滑的原理
2.掌握图像处理的基本方法二、试验设备
1.PC兼容机一台:
操作系统为WindowsXP(WindowsNT、Windows98、Windows2000),
Windows操作系统的内核如果是NT的英安装相应的补丁程序(如:
Windows2000为ServicePack3,WindowsXP为ServicePack1);
2.CodeComposerStudio3.3软件开发环境;
3.软件仿真可以不要实验箱。
三、试验原理
●邻域平均法图像平滑
假设待处理的图像为f(x,y),处理后图像为g(x,y),领域平均法图像平滑处理的数学表达可表示为:
式中f(x,y)为N*N的阵列,x,y=0,1,2,…,N-1,S是以(x,y)点为中心的邻域的集合,
M为邻域S中的像素点数。
在具体平滑运算过程中,领域S的形状和大小根据图像特点来确定,一般取的形状是正方形、矩形及十字形等,如图所示,是S邻域取四点邻域和八点邻域的示例,并且S的形状和大小可以在全图处理过程中始终保持不变,也可以根据图像的局部统计特性而变化,点(x,y)一般位于S的中心。
如S为3*3邻域,点(x,y)位于S中心,则公式变为:
●加权平均法图像平滑
加权平均法的基本思路是:
对于同一尺寸的模板,可对不同位置的加权系数采用不同的数值。
一般认为离对应模板中心像素近的像素应对滤波结果有较大贡献,所以接近模板中心的系数可较大,而模板边界附近的系数应较小。
图像邻域加权平均就是用像素的某邻域内诸像素灰度的加权平均值来代替原像素的灰度值,从而达到消除噪声的干扰的目的。
其数学计算式为:
其中W(i,j,K,L)是邻域Uij内对应于像素(KL)的加权值,为了使加权平均后图像平均亮度不发生较大的变化,要求所有权值之和为1,即:
如果邻域内各加权系数均相等时,即
,则加权平均方法变成了邻
域平均法,也就是说,邻域平均法是加权平均法中的一种特例。
在实际应用中,为保证各模板系数均为整数以减少计算量,常取模板周边最小的系数为1,而取内部的系数成比例增加,中心系数最大。
一种常用的加权平均方法是根据系数与模板中心的距离成反比来确定其他内部系数的值,常用的加权模板有:
四、实验步骤
1.设置CCS工作在软件仿真环境(Simulator),且启动CCS。
2打开\Lab4_ImgSmooth\image642.pjt工程,编译并运行程序(要求:
仿真阅读代码,按要求编写程序、调试程序、观察实验结果)。
3.运行程序,按如下方法观察试验结果。
五、实验结果
按如下方法观看试验结果:
(1)编译、链接程序:
执行菜单Project/RebuildAll,汇编结果在将汇编信息输出窗口中给出。
编译后将在Debug目录中产生一个ImgSmooth.out文件。
(2)加载程序:
执行File/LoadProgram,选择ImgSmooth.out并打开,即将可执行文件加载到DSP软件仿真器simulator中,此时CCS将自动打开一个反汇编窗口。
(3)将图像的数据从dat文件读入到内存:
执行File/data/load,将要进行颜色转换的图像数据从Data160x160.dat(说明:
*.dat格式,内部存放了某图像各像素的灰度值)文件中加载入到数据存储器,即在弹出的窗口中输入存储地址IMG与数据的长度,如下图所示。
(4)运行程序:
执行Debug/Run。
为了便于观看试验前后的结果,可以在程序中设置断点,采用单步执行的方法运行程序。
(5)显示平滑前的噪声图像:
执行View/Graph/Image,在弹出的对话框中选择颜色类型为
RGB,并输入RGB彩色图像三个通道数据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如图所示。
这样,原始的噪声图像如图所示。
(6)显示平滑后的图像:
执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入灰度图像据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如图3所示。
如图所示,是采用“3*3模板”进行邻域平均法得到的平滑图像。
读者也可以自己编写子函数,实现其他的图像平滑算法,编译运行程序,以同样的方法观看不同方法所得到的平滑效果。
平滑前后对比:
六、作业与思考
1、拓展编程:
编写通常邻域平均图像平滑函数,即:
voidIMG_Smooth_R
(unsignedchar*F,/*输入带有噪声的灰度图像*/unsignedchar*G,/*输出的平滑后的灰度图像*/intcols,introws,/*图像的宽度与高度*/intR/*邻域半径(设取奇数)*/
)
2、编程实现加权平均法图像平滑算法,分析对比实验结果和效果。
PS:
Deadline:
2018/10/29,本次作业占平时成绩5%
答案:
/*========头文件引用===========*/
#include"stdio.h"
/*=============工作变量定义======*/
unsignedchar*pr_n;//指针定义
unsignedchar*pr_s;//指针定义
//说明:
定义数据存放变量
#pragmaDATA_SECTION(IMG,"data");
intIMG[30000];
#pragmaDATA_SECTION(Noise_IMG,"data");
unsignedcharNoise_IMG[30000];
#pragmaDATA_SECTION(Smooth_IMG,"data");
unsignedcharSmooth_IMG[30000];
voidIMG_Smooth_R();
voidIMG_Smooth_A();
/*=================主程序================*/
main()
//flag=1,采用通用领域平均法算法
//flag=2,采用H3模板加权平均法算法
{intflag=2;
longn;
intimgH,imgW;
int*ptr;
imgH=160;//图像高与宽,因为数据文件中的图像是160X160像素的
imgW=160;
/*===========初始化==========*/
//1把图像数据从IMG中移到Noise_IMG数组中
ptr=IMG;
pr_n=Noise_IMG;
for(n=0;n*pr_n++=*ptr++;
//说明:
在此暂停,可看到噪声图像
//指针指向数组
pr_n=Noise_IMG;
pr_s=Smooth_IMG;
//2调用子程序,进行彩色图像变换成灰度图像
while
(1)
{
if(flag==1){
//通用领域平均法
IMG_Smooth_R(pr_n,pr_s,imgW,imgH,3);
}
//采用加权平滑算法
else{
IMG_Smooth_A(pr_n,pr_s,imgW,imgH,3);
}
//说明:
上面子程序执行后,在此暂停,可看平滑后的图像
}
//说明:
在此暂停,可看变换后的灰度图像
}
/*==============子程序=============*/
//说明:
通用的邻域平均法图像平滑算法
voidIMG_Smooth_R
(unsignedchar*F,/*输入带有噪声的灰度图像*/
unsignedchar*G,/*输出的平滑后的灰度图像*/
intcols,introws,
intR/*图像的宽度与高度*/
)
{//定义局部变量
inti,j;
unsignedchar*ptr,*pp,*newpp;
inttmpNum,x,y;
//图像四周的像素不进行平滑,等于原值
for(x=0;xG[x]=F[x];
//处理最后一行的像素
newpp=G+(rows-1)*cols;//指针指向平滑图像
pp=F+(rows-1)*cols;//指针指向噪声图像
for(x=0;x*newpp++=*pp++;
//处理最左边一列的像素
newpp=G;//指针指向平滑图像
pp=F;//指针指向噪声图像
for(y=0;y{
*newpp=*pp;
newpp+=cols;pp+=cols;//指针偏移到下一行像素的位置
}
//处理最右边一列的像素
newpp=G+cols;//指针指向平滑图像
pp=F+cols;//指针指向噪声图像
for(y=0;y{
*newpp=*pp;
newpp+=cols;pp+=cols;//指针偏移到下一行像素的位置
}
//采用循环的方式对图像中的每个像素进行平滑
for(y=1;yfor(x=1;x{
newpp=G+y*cols+x;//指针指向平滑图像
pp=F+y*cols+x;//指针指向噪声图像
//循环累加领域内各个像素
ptr=pp;
for(i=-R/2;i<=R/2;i++){
for(j=-R/2;j<=R/2;j++){
tmpNum+=*(ptr+i*cols+j);
}
}
//取平均值
tmpNum/=R*R;
//检测数据是否溢出,且将平均值赋给平滑图像
if(tmpNum>255)
*newpp=255;
else
*newpp=tmpNum;
}
}//程序结束
//加权平均法图像平滑算法
voidIMG_Smooth_A
(unsignedchar*F,/*输入带有噪声的灰度图像*/
unsignedchar*G,/*输出的平滑后的灰度图像*/
intcols,introws,
intR/*图像的宽度与高度*/
)
{//定义局部变量
unsignedchar*ptr,*pp,*newpp;
inttmpNum,x,y;
//图像四周的像素不进行平滑,等于原值
for(x=0;xG[x]=F[x];
//处理最后一行的像素
newpp=G+(rows-1)*cols;//指针指向平滑图像
pp=F+(rows-1)*cols;//指针指向噪声图像
for(x=0;x*newpp++=*pp++;
//处理最左边一列的像素
newpp=G;//指针指向平滑图像
pp=F;//指针指向噪声图像
for(y=0;y{
*newpp=*pp;
newpp+=cols;pp+=cols;//指针偏移到下一行像素的位置
}
//处理最右边一列的像素
newpp=G+cols;//指针指向平滑图像
pp=F+cols;//指针指向噪声图像
for(y=0;y{
*newpp=*pp;
newpp+=cols;pp+=cols;//指针偏移到下一行像素的位置
}
//采用循环的方式对图像中的每个像素进行平滑
for(y=1;yfor(x=1;x{
newpp=G+y*cols+x;//指针指向平滑图像
pp=F+y*cols+x;//指针指向噪声图像
//采用H3加权模板
ptr=pp;
tmpNum=*ptr;
tmpNum+=*(-R/2+ptr)/4;
tmpNum+=*(ptr+1)/4;
tmpNum+=*(ptr-1)/4;
tmpNum+=*(R/2+ptr)/4;
//取平均值
tmpNum/=2;
//检测数据是否溢出,且将平均值赋给平滑图像
if(tmpNum>255)
*newpp=255;
else
*newpp=tmpNum;
}
}//程序结束