当前位置:文档之家› 数字图像处理图像平滑

数字图像处理图像平滑

1实验目的、要求实验目的:(1)掌握图像滤波的原理与相关方法。

(2)能使用VC++实现若干种图像滤波技术。

实验要求:A部分:(1)使用VC++设计程序:对一幅256级灰度图像,使用邻域平均平滑算法进行滤波。

(2)使用VC++设计程序:对一幅256级灰度图像,使用中值滤波算法进行滤波。

(3)使用VC++设计程序:对一幅256级灰度图像,使用K近邻均值滤波器(KNNF)进行滤波。

B部分:(1)包括A部分全部要求。

(2)使用VC++设计程序:对一幅256级灰度图像,分别使用K近邻中值滤波器(KNNMF)、最小均方差滤波器进行滤波。

(3)使用VC++设计程序:对一幅24位彩色图像,使用矢量中值滤波算法进行滤波。

2实验原理图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。

由于成像系统、传输介质和记录设备等的不完善,数字图像在其形成、传输记录过程中往往会受到多种噪声的污染。

另外,在图像处理的某些环节当输入的像对象并不如预想时也会在结果图像中引入噪声。

这些噪声在图像上常表现为一引起较强视觉效果的孤立象素点或象素块。

一般,噪声信号与要研究的对象不相关它以无用的信息形式出现,扰乱图像的可观测信息。

对于数字图像信号,噪声表为或大或小的极值,这些极值通过加减作用于图像象素的真实灰度值上,在图像造成亮、暗点干扰,极大降低了图像质量,影响图像复原、分割、特征提取、图识别等后继工作的进行。

要构造一种有效抑制噪声的滤波机必须考虑两个基本问题:能有效地去除目标和背景中的噪声,同时能很好地保护图像目标的形状、大小及特定的几何和拓扑结构特征。

彩色图像矢量中值滤波算法:矢量中值滤波器(Vector Median Filter,VMF)是一种基本矢量滤波器。

它的滤波方法是对图像上的每个像素点建立一个以其为中心的滤波窗口(窗口大小为3×3、5×5等),从该滤波窗口中找到一个到其它像素的聚合距离最小的像素,然后将该像素选取为滤波器的输出。

VMF选取的聚合距离是指像素到其他像素的欧几里德距离(Euclidean Distance)之和。

3主要设备、器材硬件环境:AMD A8-4500M 1.90G/4G RAM软件环境:操作系统:WIN7开发工具:Micrsoft Visual C++ 6.04实验步骤及原始数据记录关键代码说明:添加随机噪声:void CDib::AddRandomNoise(){// 是否图像为空if( IsEmpty() ){return;}RGBQUAD rgbQuad1;int i,j;DWORD temp;for(i=0; i<m_lpBMIH->biWidth; i++){for(j=0; j<m_lpBMIH->biHeight; j++){rgbQuad1 = GetPixel(i,j);temp = rand()%30;rgbQuad1.rgbRed = rgbQuad1.rgbRed*226/256 + temp;rgbQuad1.rgbGreen = rgbQuad1.rgbGreen*226/256 + temp;rgbQuad1.rgbBlue = rgbQuad1.rgbBlue*226/256 + temp;SetPixel(i, j, &rgbQuad1);}}}添加椒盐噪声:void CDib::AddSaltNoise(){// 是否图像为空if( IsEmpty() ){return;}RGBQUAD rgbQuad1;int i,j;DWORD temp;for(i=0; i<m_lpBMIH->biWidth; i++){for(j=0; j<m_lpBMIH->biHeight; j++){rgbQuad1 = GetPixel(i,j);temp = rand()%100;if( temp==0 ){rgbQuad1.rgbRed = 0;rgbQuad1.rgbGreen = 0;rgbQuad1.rgbBlue = 0;SetPixel(i, j, &rgbQuad1);}else if( temp==1 ){rgbQuad1.rgbRed = 255;rgbQuad1.rgbGreen = 255;rgbQuad1.rgbBlue = 255;SetPixel(i, j, &rgbQuad1);}}}}邻域平均滤波:void CImageProcessingView::OnEnhanceDenoiseAverage() {// 实验图像平滑256级灰度图像邻域平均滤波// 获得当前文档对象CImageProcessingDoc* pDoc = GetDocument();if( pDoc->m_pDibInit->IsEmpty() ){MessageBox("图像未加载");return;}// 获得图像的基本信息int width = pDoc->m_pDibInit->GetImageWidth();int height = pDoc->m_pDibInit->GetImageHeight();int bitCount = pDoc->m_pDibInit->GetImageBitCount();// 程序只支持处理灰度图像if( bitCount!=8 ){MessageBox("目前只支持256级灰度图像");return;}// 将图像信息复制至m_pDibTestpDoc->m_pDibTest->CloneDib(pDoc->m_pDibInit);// 设置去噪模板,这里使用一个3×3的去噪模板double templateDenoise[100] ={1, 1, 1,1, 2, 1,1, 1, 1};int templateWidth = 3;int templateHeight = 3;int templateElementCnt = templateWidth*templateHeight;double sum1 = 0;// 归一化模板元素的值int i;for(i=0; i<templateElementCnt; i++)sum1 += templateDenoise[i];for(i=0; i<templateElementCnt; i++)templateDenoise[i] = templateDenoise[i]/sum1;// 定义临时变量int j,m,n;BYTE gray;double value1;// 对图像里面的每一个像素进行邻域// 为了方便,这里没有处理边界点for(i=templateWidth/2; i<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateWidth/2; i++){for(j=templateHeight/2;j<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateHeight/2; j++){// 当前的像素点是(i, j) 。

// 计算以(i, j) 为中心,templateWidth为宽度,templateHeight为高度的矩形区域内,个个像素点颜色值的加权和。

// 因为现在处理的是256色灰度图像,所以在RGBQUAD结构中,Red、Green、Blue三个分量的值都肯定是相等的,// 所以只要处理Red分量,算出的结果也适用于Green分量和Blue分量value1 = 0;for(m=0; m<templateWidth; m++){for(n=0; n<templateHeight; n++){gray = pDoc->m_pDibInit->GetGray(i-templateWidth/2+m, j-templateHeight/2+n);value1 += gray * templateDenoise[n*templateWidth+m];}}pDoc->m_pDibTest->SetGray(i, j, value1);}}// 交换指针CDib* pTmpDib = pDoc->m_pDibTest;pDoc->m_pDibTest = pDoc->m_pDibInit;pDoc->m_pDibInit = pTmpDib;// 设置脏标记pDoc->SetModifiedFlag(TRUE);// 更新视图pDoc->UpdateAllViews(NULL);}中值滤波:void CImageProcessingView::OnEnhanceDenoiseMedian(){// 实验图像平滑256级灰度图像中值滤波// 参考CImageProcessingView::OnEnhanceDenoiseAverage()MessageBox("请在这里设计256级灰度图像中值滤波算法");// 获得当前文档对象CImageProcessingDoc* pDoc = GetDocument();if( pDoc->m_pDibInit->IsEmpty() ){MessageBox("图像未加载");return;}// 获得图像的基本信息int width = pDoc->m_pDibInit->GetImageWidth();int height = pDoc->m_pDibInit->GetImageHeight();int bitCount = pDoc->m_pDibInit->GetImageBitCount();// 程序只支持处理灰度图像if( bitCount!=8 ){MessageBox("目前只支持256级灰度图像");return;}// 将图像信息复制至m_pDibTestpDoc->m_pDibTest->CloneDib(pDoc->m_pDibInit);int i,j,m,n;BYTE grays[100];int graysSize = 100;int templateWidth = 3;int templateHeight = 3;int templateElementCnt = templateWidth*templateHeight;BYTE tempByte1;for(i=templateWidth/2; i<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateWidth/2; i++){for(j=templateHeight/2;j<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateHeight/2; j++){memset(grays, 0, graysSize*sizeof(BYTE));for(n=0; n<templateHeight; n++){for(m=0; m<templateWidth; m++){grays[n*templateWidth+m] = pDoc->m_pDibInit->GetGray(i-templateWidth/2+m, j-templateHeight/2+n);}}for(m=0; m<templateElementCnt-1; m++){for(n=m+1; n<templateElementCnt; n++){if( grays[m]>grays[n] ){tempByte1 = grays[m];grays[m] = grays[n];grays[n] = tempByte1;}}}pDoc->m_pDibTest->SetGray(i, j, grays[templateElementCnt/2]);}}// 交换指针CDib* pTmpDib = pDoc->m_pDibTest;pDoc->m_pDibTest = pDoc->m_pDibInit;pDoc->m_pDibInit = pTmpDib;// 设置脏标记pDoc->SetModifiedFlag(TRUE);// 更新视图pDoc->UpdateAllViews(NULL);}K近邻均值滤波:void CImageProcessingView::OnEnhanceDenoiseKNNF(){// 实验图像平滑256级灰度图像KNNF滤波// 参考CImageProcessingView::OnEnhanceDenoiseAverage()MessageBox("请在这里设计256级灰度图像KNNF滤波算法");// 获得当前文档对象CImageProcessingDoc* pDoc = GetDocument();if( pDoc->m_pDibInit->IsEmpty() ){MessageBox("图像未加载");return;}// 获得图像的基本信息int width = pDoc->m_pDibInit->GetImageWidth();int height = pDoc->m_pDibInit->GetImageHeight();int bitCount = pDoc->m_pDibInit->GetImageBitCount();// 程序只支持处理灰度图像if( bitCount!=8 ){MessageBox("目前只支持256级灰度图像");return;}// 将图像信息复制至m_pDibTestpDoc->m_pDibTest->CloneDib(pDoc->m_pDibInit);int i,j,m,n;BYTE grays[100];int graysSize = 100;int templateWidth = 3;int templateHeight = 3;int templateElementCnt = templateWidth*templateHeight;BYTE tempByte1;int kNN = 3;for(i=templateWidth/2; i<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateWidth/2; i++){for(j=templateHeight/2;j<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateHeight/2; j++){memset(grays, 0, graysSize*sizeof(BYTE));for(n=0; n<templateHeight; n++){for(m=0; m<templateWidth; m++){grays[n*templateWidth+m] = pDoc->m_pDibInit->GetGray(i-templateWidth/2+m, j-templateHeight/2+n);}}BYTE centerGray = pDoc->m_pDibInit->GetGray(i, j);for(m=0; m<templateElementCnt-1; m++){for(n=m+1; n<templateElementCnt; n++){if( abs(grays[m]-centerGray) > abs(grays[n]-centerGray) ){tempByte1 = grays[m];grays[m] = grays[n];grays[n] = tempByte1;}}}double avgGray = 0;for(m=0; m<kNN; m++){avgGray += grays[m];}avgGray /= kNN;pDoc->m_pDibTest->SetGray(i, j, avgGray);}}// 交换指针CDib* pTmpDib = pDoc->m_pDibTest;pDoc->m_pDibTest = pDoc->m_pDibInit;pDoc->m_pDibInit = pTmpDib;// 设置脏标记pDoc->SetModifiedFlag(TRUE);// 更新视图pDoc->UpdateAllViews(NULL);}K近邻均值滤波:void CImageProcessingView::OnEnhanceDenoiseKNNF(){// 实验图像平滑256级灰度图像KNNF滤波// 参考CImageProcessingView::OnEnhanceDenoiseAverage()MessageBox("请在这里设计256级灰度图像KNNF滤波算法");// 获得当前文档对象CImageProcessingDoc* pDoc = GetDocument();if( pDoc->m_pDibInit->IsEmpty() ){MessageBox("图像未加载");return;}// 获得图像的基本信息int width = pDoc->m_pDibInit->GetImageWidth();int height = pDoc->m_pDibInit->GetImageHeight();int bitCount = pDoc->m_pDibInit->GetImageBitCount();// 程序只支持处理灰度图像if( bitCount!=8 ){MessageBox("目前只支持256级灰度图像");return;}// 将图像信息复制至m_pDibTestpDoc->m_pDibTest->CloneDib(pDoc->m_pDibInit);int i,j,m,n;BYTE grays[100];int graysSize = 100;int templateWidth = 3;int templateHeight = 3;int templateElementCnt = templateWidth*templateHeight;BYTE tempByte1;int kNN = 3;for(i=templateWidth/2; i<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateWidth/2; i++){for(j=templateHeight/2;j<pDoc->m_pDibInit->m_lpBMIH->biWidth-templateHeight/2; j++){memset(grays, 0, graysSize*sizeof(BYTE));for(n=0; n<templateHeight; n++){for(m=0; m<templateWidth; m++){grays[n*templateWidth+m] = pDoc->m_pDibInit->GetGray(i-templateWidth/2+m, j-templateHeight/2+n);}}BYTE centerGray = pDoc->m_pDibInit->GetGray(i, j);for(m=0; m<templateElementCnt-1; m++){for(n=m+1; n<templateElementCnt; n++){if( abs(grays[m]-centerGray) > abs(grays[n]-centerGray) ){tempByte1 = grays[m];grays[m] = grays[n];grays[n] = tempByte1;}}}double avgGray = 0;for(m=0; m<kNN; m++){avgGray += grays[m];}avgGray /= kNN;pDoc->m_pDibTest->SetGray(i, j, avgGray);}}// 交换指针CDib* pTmpDib = pDoc->m_pDibTest;pDoc->m_pDibTest = pDoc->m_pDibInit;pDoc->m_pDibInit = pTmpDib;// 设置脏标记pDoc->SetModifiedFlag(TRUE);// 更新视图pDoc->UpdateAllViews(NULL);}实验数据记录:实验图像:实验图像说明:左上:添加椒盐噪声图像中上:对椒盐噪声进行邻域平均滤波后右上:对椒盐噪声进行K近邻均值滤波左下:添加随机噪声图像中下:对随机噪声进行中值滤波后。

相关主题