设为首页 加入收藏

TOP

5.2.2 编程实现噪声添加
2013-10-07 00:23:05 来源: 作者: 【 】 浏览:60
Tags:5.2.2 编程 实现 噪声 添加

5.2.2  编程(www.cppentry.com)实现噪声添加

在实际应用中,为了验证噪声去除算法的有效性,有时需要在图像上模拟添加各种不同类型的噪声。本节介绍两种模拟图像噪声的方法:一是添加椒盐噪声;二是添加随机噪声。

椒盐噪声是一种在图像中产生黑色、白色点状脉冲噪声的常见噪声形式,在模拟添加噪声过程中,利用产生随机数函数rand()的方法给图像添加椒盐噪声。

在图像中添加随机噪声的思路就是对于图像中的每一个像素,首先由系统随机产生一个随机数,然后利用图像的像素值与该随机数相加,把所得的结果作为图像的像素值。对于8位的灰度图像,为了避免像素值相加后的结果大于255,所以要对像素值进行归一化处理。
添加椒盐噪声的函数名为AddPepperSaltNoise(),它定义在demo程序的图像增强类CImgEnhance中。AddPepperSaltNoise()函数的说明及代码实现如下:

 /***************************************
*******************************
*
* 函数名称:
*     AddPepperSaltNoise()
*
* 参数:
*     void
*
* 返回值:
*     void
*
* 说明:在view中为图像添加椒盐噪声
*    
*
********************************************
**************************/
void CImgEnhance::AddPepperSaltNoise()
{
unsigned char* pDIB;
int bytecount,i;
if(m_pImgDataOut!=NULL)
{
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
pDIB=m_pImgData;
if(m_nBitCount==8||m_nBitCount==24)
{
bytecount = m_imgWidth * m_imgHeight *m_nBitCount/8;
//获取位图数据区的字节数
}
else
{
AfxMessageBox("只能处理真彩色和8位灰度图像!");
return ;
}
if (m_nBitCount==8)      //处理灰度图像

for (i=0;i<bytecount;i++)
{
if(rand()>32000)  pDIB[i]=0;
if(rand()<200)    pDIB[i]=255;
}
}
else                  //处理24位真彩色图像
{
for (i=0;i<bytecount;i=i+3)
{
int num=rand();
if (num>32000)
{
pDIB[i]=(rand())%255;        //处理每一个像素的RGB值
pDIB[i+1]=(rand())%255;
pDIB[i+2]=(rand())%255;
}
if (num<200)
{
pDIB[i]=(rand())%255;
pDIB[i+1]=(rand())%255;
pDIB[i+2]=(rand())%255;
}
}
}
//生成新的DIB位图
m_nBitCountOut=m_nBitCount;
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
if (!m_pImgDataOut)
{
m_pImgDataOut=new unsigned char
[lineByteOut*m_imgHeight];
}
int j, pixelByte=m_nBitCountOut/8;
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth*pixelByte;j++)
*(m_pImgDataOut+i*lineByteOut+j)= *
(pDIB+i*lineByteOut+j);
}
}
添加随机噪声的函数名为AddRandomNoise(),它定义在demo程序的图像增强类CImgEnhance中。
 /***************************************
*******************************
*
* 函数名称:
*     AddRandomNoise()
*
* 参数:
*     void
*
* 返回值:
*     void
*
* 说明:在view中为图像添加随机噪声
*    
*
***************************************
*******************************/
void CImgEnhance::AddRandomNoise()
{
unsigned char* pDIB;
int bytecount,i;
if(m_pImgDataOut!=NULL)
{
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
pDIB=m_pImgData;
if(m_nBitCount==8)
{
bytecount = m_imgWidth * m_imgHeight *m_nBitCount/8;
//获取位图数据区的字节数
}
else
{
AfxMessageBox("只能处理8位灰度图像!");
return ;
}
//在DIB中添加随机噪声 
for( i=0;i<bytecount;i++)
{
LONG Temp=rand();
Temp=pDIB[i]*224/256+Temp/512;
pDIB[i]=Temp>=255 255:Temp;
}

m_nBitCountOut=m_nBitCount;
int lineByteOut=(m_imgWidth*m_nBitCountOut/8+3)/4*4;
if (!m_pImgDataOut)
{
m_pImgDataOut=new unsigned char
[lineByteOut*m_imgHeight];
}

int j, pixelByte=m_nBitCountOut/8;
for(i=0;i<m_imgHeight;i++){
for(j=0;j<m_imgWidth*pixelByte;j++)
*(m_pImgDataOut+i*lineByteOut+j)= *
(pDIB+i*lineByteOut+j);
}

}

函数调用

在视图类CDemoView中映射添加噪声事件的处理函数。以下是CDemoView:: OnPepperSaltNoise()函数和CDemoView::OnRandom()函数的代码实现。

void CDemoView::OnRandom() 
{
CDemoDoc *pDoc=GetDocument();
ImgCenterDib *pDib=pDoc->GetPDib();

if(pDib->m_nBitCount!=8
::MessageBox(0,"只处理灰度图像",MB_OK,0);
return ;
}

CImgEnhance imgnoise(pDib->GetDimensions(),
pDib->m_nBitCount,
pDib->m_lpColorTable, pDib->m_pImgData);
imgnoise.AddRandomNoise();

CMainFrame* pFrame = (CMainFrame *)
(AfxGetApp()->m_pMainWnd);
pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);

CDemoView* pView=(CDemoView*)pFrame->
MDIGetActive()->GetActiveView();
CDemoDoc* pDocNew=pView->GetDocument();
ImgCenterDib *dibNew=pDocNew->GetPDib();

dibNew->ReplaceDib(imgnoise.GetDimensions(),
imgnoise.m_nBitCountOut,imgnoise.
m_lpColorTable, imgnoise.m_pImgDataOut);
pDocNew->SetModifiedFlag(TRUE);
pDocNew->UpdateAllViews(pView);

Invalidate();

}

void CDemoView::OnAveSmooth()
{
CDemoDoc *pDoc=GetDocument();
ImgCenterDib *pDib=pDoc->GetPDib();

if(pDib->m_nBitCount!=8
::MessageBox(0,"只处理灰度图像",MB_OK,0);
return ;
}

CImgEnhance imgnoise(pDib->GetDimensions(),pDib->m_nBitCount,
pDib->m_lpColorTable, pDib->m_pImgData);
int TH, TW, TCX, TCY;
float fCoef;
float T[9];
//设模板为平均模板
T[0]=1.0;
T[1]=1.0;
T[2]=1.0;
T[3]=1.0;
T[4]=1.0;
T[5]=1.0;
T[6]=1.0;
T[7]=1.0;
T[8]=1.0;
//初始化对话框变量
TH=3;
TW=3;
TCX=1;
TempCY=1;
fCoef=(float)(1.0/9.0);
imgnoise.AvgTemplate(TempH,TempW,TempCX,TempCY,Temp,fCoef);

CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd);
pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);

CDemoView* pView=(CDemoView*)pFrame->MDIGetActive()->GetActiveView();
CDemoDoc* pDocNew=pView->GetDocument();
ImgCenterDib *dibNew=pDocNew->GetPDib();

dibNew->ReplaceDib(imgnoise.GetDimensions(),
imgnoise.m_nBitCountOut,imgnoise.m_lpColorTable, imgnoise.m_pImgDataOut);
pDocNew->SetModifiedFlag(TRUE);
pDocNew->UpdateAllViews(pView);

Invalidate();
return;
}

从程序的运行效果(见图5-2)可以看到,在图像中添加噪声以后图像的质量明显下降,不同类型的噪声对图像质量的影响不同,这可以从图像的信噪比数值上体现出来。


 
(点击查看大图)图5-2  对原始图像添加噪声的实验结果
【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇5.3.2 其他灰度修正方法 下一篇5.1 图像增强类

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: