图像噪声抑制和图像锐化程序设计.docx
《图像噪声抑制和图像锐化程序设计.docx》由会员分享,可在线阅读,更多相关《图像噪声抑制和图像锐化程序设计.docx(36页珍藏版)》请在冰豆网上搜索。
图像噪声抑制和图像锐化程序设计
*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2009年秋季学期
计算机图象处理综合训练
题目:
图像噪声抑制和图像锐化程序设计
专业班级:
姓名:
学号:
指导教师:
成绩:
摘要
噪声是不可预测的随机信号,通常采用概率统计方法对其进行分析。
噪声对图像处理十分重要,它影响图像处理的输入、采集、处理的各个环节以及输出结果的全过程。
特别是图像处理的输入、采集噪声的抑制是十分关键的问题,若输入伴有较大的噪声,必然影响处理全过程及输出结果。
图像锐化的主要目的是突出图像中的细节或者增强被模糊了的细节。
模糊可能是由于错误操作,或者由于图像获取方法的固有影响所导致的。
本次图象处理涉及到噪声抑制程序设计和图像锐化程序设计,涉及到图像噪声抑制处理的方法有中值滤波,涉及到图像锐化处理的方法有laplacian微分算子,通过它们分别来实现图像的噪声抑制和锐化。
在图像处理中主要用VC++编写图像处理程序,并调用C++图像处理的部分内部函数进行处理。
关键词:
图像处理;噪声抑制;图像锐化;中值滤波;laplacian微分算子;
一、前言
图像处理即数字图像处理(DigitalImageProcessing),又称为计算机图像处理,它是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。
图像信息在采集过程中往往受到各种噪声源的干扰,这些噪声在图像上常常表现为一些孤立像素点,这可理解为像素的灰度分布是空间相关的,即噪声点像素灰度与它们临近像素的灰度有着显著不同。
这种干扰或孤立像素点如不经过滤波处理,会对以后的图像区域分割、分析和判断带来影响。
图像经常会由于错误操作,或者是由于图像获取方法的固有影响而导致模糊。
有时候也需要进一步获得图像的细节。
图像锐化使得模糊了的细节得以增强以及突出图像中的细节。
本此图像处理实现对图像进行中值滤波噪声抑制和laplacian锐化处理,使图像的画面更加清晰,提取的细节更多。
二、算法分析与描述
2.1中值滤波
中值滤波法是一种非线性处理技术,可用来抑制图象中的噪音而且保持轮廓的清晰。
中值滤波的方法就是把以某点(i,j)为中心的小窗口内的所有像素的灰度按从大到小的顺序排列,将中间值作为(i,j)处的灰度值(若窗口中有偶数个像素,则取两个中间值的平均)。
例如:
中值滤波的模板可以是一维的(水平的或垂直的),也可以是二维的。
当某个像素的灰度值超过窗口中像素灰度值排序中间的那个值,且达到一定水平时,则判断该点为噪声,用灰度值排序中间的那个值来代替;否则还是保持原来的灰度值。
中值滤波后的图像边缘得到了较好的保护
2.2拉普拉斯(Laplacian)微分算子
最简单的二阶各向同性微分算子是拉普拉斯微分算子,二维图像f(x,y)的拉普拉斯微分算子定义为:
写成模板系数形式形式即为Laplacian算子:
二阶微分算子所提取出的细节较一阶微分算子提出的细节多,表明了二阶微分算子在对图像细节更加敏感。
三、详细设计过程
3.1中值滤波程序流程图
MedianFilter()中值滤波
lpImage;临时存放图像数据的指针
GetMedianValue()获取中值,该函数用冒泡法对一维数组进行排序,并返回数组元素的中值。
,memcpy()复制变换后的图像
是
图3.2中值滤波程序流程图
3.2laplacian程序流程图
函数名称:
LaplacianDIB()
参数:
LPSTRlpDIBBits-指向源DIB图像指针
LONGlWidth-源图像宽度(象素数,必须是4的倍数)
LONGlHeight-源图像高度(象素数)
返回值:
BOOL-边缘检测成功返回TRUE,否则返回FALSE。
说明:
该函数用laplacian微分算子对图像进行锐化运算。
四、调试过程中出现的问题及相应解决办法
4.1出现的问题
编译图像几何变换的程序时,出现了下面三个问题:
(3)fatalerrorC1010:
unexpectedendoffilewhilelookingforprecompiledheaderdirective
这个问题是由于缺少头文件“stdafx.h”
图4.1程序编译出错界面
4.2解决问题
在C++语言中,要调用的很多东西都包含在头文件中,所以加上头文件#include"stdafx.h",程序就编译成功了。
五、程序运行截图及其说明
5.1原图
图5.1人物原图
5.2对图像进行中值滤波处理
由上图对比可以看到经过中值滤波处理后的人物图片,画面的清晰度基本保持,同时噪声也得到抑制。
图5.2中值滤波后的人物图
5.3对图像进行laplacian锐化处理
对照人物原图,可以看出,经过laplacian处理后的图像得到了较多的图像细节,可见Laplacian算法具有较强获得图像细节的能力。
图5.3laplacian锐化后的人物图
六、简单操作手册
6.1打开程序运行界面,如下图所示:
打开程序的运行界面,可以看到操作界面,在此界面进行对图像所需要的处理。
,
图6.1打开界面
6.2选择图片如下图所示:
在打开界面中选择文件,然后再选择打开就可以看到下图的界面,进行选择图片
图6.2图片选择界面
6.3人物原图如下图所示
以选择好待处理的图片,选择图像增强,点击下面的中值滤波,可以看到下面的界面
图6.3人物原图
6.4中值滤波选择窗口
对图片进行中值滤波处理,可以选择三个模板进行处理,下图选择3×3进行处理,点击确定后可看见下图。
6.4中值选择界面
6.5中值滤波处理后的人物图如下图所示
经过中值滤波处理好的图像
图6.5中值滤波处理后的人物图
6.6原图如下图所示:
图6.6人物原图
6.7Laplacian锐化处理如下图所示:
进行和中值滤波类似的操作对图像进行laplacian锐化处理,可以看到处理后的如下图所示
图6.7laplacian处理界面
设计总结
此次图像噪声抑制和图像锐化程序设计让我在巩固了所学的知识的同时,对所学的东西得以灵活运用,增强了动手能力以及实践能力。
在编程的过程中,使我对以前所学知识进行了系统的强化。
在掌握了计算机图象处理技术的基础知识、基本原理和方法的基础上,使用计算机图象处理方法完成图像噪声抑制和图像锐化程序设计。
通过该题目的分析和设计,让自己对所学知识、理论和方法得到巩固。
得到计算机图象处理应用的综合训练,全面培养了对图象处理程序开发过程中的分析、设计、编码、测试以及文档规范书写的能力,提高了解决实际问题的能力。
在这次课程设计中,也遇到了许多问题,如在编码阶段需要反复的对程序调试运行,出现了各种错误,因为以前对C++缺少动手编程的能力,所以编程起来就感到很困难。
在编写过程中,得到了老师和同学的许多帮助,才使我得以顺利的完成这次课程设计。
同时通过这次课程设计我也发现了很多自己的不足,比如自己的知识储备还远远不够,动手能力还需要提高,对所学过的东西掌握的不是很全面。
所以在以后的学习生活中,我一定要弥补自己的不足,在学好课本知识的同时,拓宽知识面,增强自己的动手和实践能力。
参考资料
[1]朱虹.计算机图象处理基础[M].科学出版社,2005
[2]RC.Gonzalez,RE.Woods著,阮秋琦,阮宇智等译.计算机图象处理(第2版).北京:
电子工业出版社,2003
[3]K.R.Castleman.计算机图象处理.北京:
电子工业出版社,2002
[4]章毓晋.图像处理与分析-图像工程(上册),清华大学,2001
[5]何斌等编著.VisualC++计算机图象处理.人民邮电出版社,2002
[6]张宏林编著.VisualC++计算机图象模式识别技术及工程实践.人民邮电出版社,2003.
[7]黄维通.VisualC++面向对象与可视化程序设计.清华大学出版社,2003
致谢
我在此衷心的感谢耐心教导我的柯铭老师和热心帮助我的同学。
这段时间的综合训练使我感受到老师的负责;通过和同学们的交流,让我真正感受到了团结的力量。
这次课程设计能够顺利完成要多感谢老师和同学的热心帮助。
整个课程设计都是在压力和成就感的心情下进行的,我觉得通过这次课程设计使我不仅巩固了课本知识还增长了实践能力。
感谢学校为我提供了这次实践的机会。
附录
#include"stdafx.h"
#include"cdib.h"
#include"math.h"
#include
#include
usingnamespacestd;
#include"GlobalApi.h"
/*************************************************************************
*
*\函数名称:
*GraySegLinTrans()
*
*\输入参数:
*CDib*pDib-指向CDib类的指针,含有原始图象信息
*intnX1-分段线性灰度变换第一个拐点的X坐标
*intnY1-分段线性灰度变换第一个拐点的Y坐标
*intnX2-分段线性灰度变换第二个拐点的X坐标
*intnY2-分段线性灰度变换第二个拐点的Y坐标
*
*\返回值:
*BOOL-成功返回TRUE,否则返回FALSE。
*
*\说明:
*该函数用来对图像进行分段线性灰度变换,输入参数中包含了两个拐点的坐标
*
*************************************************************************
*/
BOOLGraySegLinTrans(CDib*pDib,intnX1,intnY1,intnX2,intnY2)
{
//指向源图像的指针
unsignedchar*lpSrc;
//循环变量
inti,j;
//灰度映射表
BYTEbyMap[256];
//图像每行的字节数
//LONGlLineBytes;
//图象的高度和宽度
CSizesizeImage;
sizeImage=pDib->GetDimensions();
//获得图象数据存储的高度和宽度
CSizeSizeSaveImage;
SizeSaveImage=pDib->GetDibSaveDim();
//计算图像每行的字节数
//lLineBytes=WIDTHBYTES(sizeImage.cx*8);
//计算灰度映射表
for(i=0;i<=nX1;i++)
{
//判断nX1是否大于0(防止分母为0)
if(nX1>0)
{
//线性变换
byMap[i]=(BYTE)nY1*i/nX1;
}
else
{
//直接赋值为0
byMap[i]=0;
}
}
for(;i<=nX2;i++)
{
//判断nX1是否等于nX2(防止分母为0)
if(nX2!
=nX1)
{
//线性变换
byMap[i]=nY1+(BYTE)((nY2-nY1)*(i-nX1)/(nX2-nX1));
}
else
{
//直接赋值为nY1
byMap[i]=nY1;
}
}
for(;i<256;i++)
{
//判断nX2是否等于255(防止分母为0)
if(nX2!
=255)
{
//线性变换
byMap[i]=nY2+(BYTE)((255-nY2)*(i-nX2)/(255-nX2));
}
else
{
//直接赋值为255
byMap[i]=255;
}
}
//对图象的象素值进行变换
//每行
for(i=0;i{
//每列
for(j=0;j{
//指向DIB第i行,第j个象素的指针
lpSrc=(unsignedchar*)pDib->m_lpImage+pDib->GetPixelOffset(i,j);
//计算新的灰度值
*lpSrc=byMap[*lpSrc];
}
}
//返回
returnTRUE;
}
/*************************************************************************
*
\函数名称:
GeneralTemplate()
\输入参数:
CDib*pDib-指向CDib类的指针,含有原始图象信息
intnTempWidth-模板的宽度
intnTempHeight-模板的高度
intnTempCenX-模板中心的X坐标(相对于模板)
intnTempCenY-模板中心的Y坐标(相对于模板)
double*pdbTemp-模板数组的指针
double*dbCoef-模板的系数
\返回值:
BOOL-成功则返回TRUE,否则返回FALSE
\说明:
该函数用指定的模板对pDib指向的图象进行模板操作。
模板的定义了宽度,高度,
*中心坐标和系数,模板的数据存放在pdbTemp中。
对图象进行模板操作后,仍
*然存放在pDib指向的CDib对象中。
需要注意的是,该函数只能处理8位的图象,
*否则,指向的数据将出错。
*
*************************************************************************
*/
BOOLGeneralTemplate(CDib*pDib,intnTempWidth,intnTempHeight,
intnTempCenX,intnTempCenY,
double*pdbTemp,doubledbCoef)
{
//临时存放图像数据的指针
LPBYTElpImage;
//循环变量
inti,j,k,l;
//指向源图像的指针
unsignedchar*lpSrc;
//指向要复制区域的指针
unsignedchar*lpDst;
//计算结果
doubledbResult;
//图象的高度和宽度
CSizesizeImage;
sizeImage=pDib->GetDimensions();
//获得图象数据存储的尺寸
intnSizeImage;
nSizeImage=pDib->GetSizeImage();
//给临时存放数据分配内存
lpImage=(LPBYTE)newchar[nSizeImage];
//判断是否内存分配失败
if(lpImage==NULL)
{
//分配内存失败
returnFALSE;
}
//将原始图像的数据拷贝到临时存放内存中
memcpy(lpImage,pDib->m_lpImage,nSizeImage);
//进行模板操作
//行(除去边缘几行)
for(i=nTempCenY;i{
//列(除去边缘几列)
for(j=nTempCenX;j{
//指向新DIB第i行,第j个象素的指针
lpDst=(unsignedchar*)lpImage+pDib->GetPixelOffset(i,j);
dbResult=0;
//计算
for(k=0;k{
for(l=0;l{
//指向DIB第i-nTempCenY+k行,第j-nTempCenX+l个象素的指针
lpSrc=(unsignedchar*)pDib->m_lpImage+pDib->GetPixelOffset(i-nTempCenY+k,j-nTempCenX+l);
//保存象素值
dbResult+=(*lpSrc)*pdbTemp[k*nTempWidth+l];
}
}
//乘上系数
dbResult*=dbCoef;
//取绝对值
dbResult=(double)fabs(dbResult);
//判断是否超过255
if(dbResult>255)
{
//直接赋值为255
*lpDst=255;
}
else
{
//赋值
*lpDst=(unsignedchar)(dbResult+0.5);
}
}
}
//复制变换后的图像
memcpy(pDib->m_lpImage,lpImage,nSizeImage);
//释放内存
delete[]lpImage;
//返回
returnTRUE;
}
/*************************************************************************
*
*函数名称:
*MedianFilter()
*
*\输入参数:
*CDib*pDib-指向CDib类的指针,含有原始图象信息
*intnTempWidth-模板的宽度
*intnTempHeight-模板的高度
*intnTempCenX-模板中心的X坐标(相对于模板)
*intnTempCenY-模板中心的Y坐标(相对于模板)
*
*\返回值:
*BOOL-成功则返回TRUE,否则返回FALSE
*
*说明:
*该函数对指定的DIB图像进行中值滤波。
*
************************************************************************/
BOOLMedianFilter(CDib*pDib,intnTempWidth,intnTempHeight,
intnTempCenX,intnTempCenY)
{
//临时存放图像数据的指针
LPBYTElpImage;
//循环变量
inti,j,k,l;
//指向源图像的指针
unsignedchar*lpSrc;
//指向要复制区域的指针
unsignedchar*lpDst;
//图象的高度和宽度
CSizesizeImage;
sizeImage=pDib->GetDimensions();
//获得图象数据存储的尺寸
intnSizeImage;
nSizeImage=pDib->GetSizeImage();
//指向滤波器数组的指针
unsignedchar*pUnchFltValue;
//给临时存放数据分配内存
lpImage=(LPBYTE)newchar[nSizeImage];
//判断是否内存分配失败
if(lpImage==NULL)
{
//返回
returnFALSE;
}
//将原始图像的数据拷贝到临时存放内存中
memcpy(lpImage,pDib->m_lpImage,nSizeImage);
//暂时分配内存,以保存滤波器数组
pUnchFltValue=newunsignedchar[nTempHeight*nTempWidth];
//判断是否内存分配失败
if(pUnchFltValue==NULL)
{
//释放已分配内存
delete[]lpImage;
//返回
returnFALSE;
}
//开始中值滤波
//行(除去边缘几行)
for(i=nTempCenY;i{
//列(除去边缘几列)
for(j=nTempCenX;j{
//指向新DIB第i行,第j个象素的指针
lpDst=(unsignedchar*)lpImage+pDib->GetPixelOffset(i,j);
//lpDst=(unsignedchar*)lpImage+sizeImage.cx*(sizeImage.cy-1-i)+j;
//读取滤波器数组
for(k=0;k{
for(l=0;l{
//指向DIB第i-nTempCenY+k行,第j-nTempCenX+l个