科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Visual C++实现数字图像增强处理

Visual C++实现数字图像增强处理

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在实际应用中,我们的系统获取的原始图像不是完美的,所以需要进行预处理,以有利于提取我们感兴趣的信息

作者:刘涛 来源:yesky 2007年11月16日

关键字: Visual C++ 数字图像增强 处理

  • 评论
  • 分享微博
  • 分享邮件
对于一个图像处理系统来说,可以将流程分为三个阶段,在获取原始图像后,首先是图像预处理阶段、第二是特征抽取阶段、第三是识别分析阶段。图像预处理阶段尤为重要,如果这阶段处理不好,后面的工作根本无法展开。
  
  在实际应用中,我们的系统获取的原始图像不是完美的,例如对于系统获取的原始图像,由于噪声、光照等原因,图像的质量不高,所以需要进行预处理,以有利于提取我们感兴趣的信息。图像的预处理包括图像增强、平滑滤波、锐化等内容。图像的预处理既可以在空间域实现,也可以在频域内实现,我们主要介绍在空间域内对图像进行点运算,它是一种既简单又重要的图像处理技术,它能让用户改变图像上像素点的灰度值,这样通过点运算处理将产生一幅新图像。下面我们开始介绍与图像点运算的相关知识。

  一、图像的直方图

  图像直方图是图像处理中一种十分重要的图像分析工具,它描述了一幅图像的灰度级内容,任何一幅图像的直方图都包含了丰富的信息,它主要用在图象分割,图像灰度变换等处理过程中。从数学上来说图像直方图是图像各灰度值统计特性与图像灰度值的函数,它统计一幅图像中各个灰度级出现的次数或概率;从图形上来说,它是一个二维图,横坐标表示图像中各个像素点的灰度级,纵坐标为各个灰度级上图像各个像素点出现的次数或概率。如果不特别说明,本讲座中的直方图的纵坐标都对应着该灰度级在图像中出现的概率。我们的例子是在一个对话框中显示一个图像的直方图,为实现该目的,我们定义了一个名为"ZFT"的对话框类用来显示图像的直方图,具体实现代码和效果图如下(关于代码实现部分可以参考笔者2001年在天极网上发表的一篇VC实现数字图像处理的文章):


//////////////////////////////////直方图对话框构造函数;
ZFT::ZFT(CWnd* pParent /*=NULL*/)
: CDialog(ZFT::IDD, pParent)//ZFT为定义的用来显示直方图的对话框类;
{
 Width=Height=0;//对话框初始化阶段设置图像的宽和高为"0";
}
////////////////////////对话框重画函数;
void ZFT::OnPaint()
{
 CRect rect;//矩形区域对象;
 CWnd *pWnd;//得到图片框的窗口指针;
 pWnd=GetDlgItem(IDC_Graphic);//得到ZFT对话框内的"Frame"控件的指针;
 file://(IDC_Graphic为放置在对话框上的一个"Picture"控件,并讲类型设置为"Frame")。
 pWnd->GetClientRect(&rect);//得到"Frame"控件窗口的"视"区域;
 int i;
 CPaintDC dc(pWnd);//得到"Frame"控件的设备上下文;
 file://画直方图的x、y轴;
 dc.MoveTo(0,rect.Height());
 dc.LineTo(rect.Width(),rect.Height());
 dc.MoveTo(0,rect.Height());
 dc.LineTo(0,0);
 file://画直方图,num[]是"ZFT"的内部数组变量,存放的是图像各个灰度级出现的概率;该数组的各个分量在  显示具体图像的直方图时设置;
 for(i=0;i<256;i++)//根据图像上的各个灰度级出现的概率,在坐标上对应的画出一根直线,从而各个表示各灰度级出现概率的直线构成了图像的直方图;
 {
  dc.MoveTo(i+1,rect.Height());
  dc.LineTo (i+1,(rect.Height()-rect.Height()*num[i]*30));
  file://此处num分量乘以"30"是为了放大个灰度级上对应的出现概率直线,增强显示效果;
 }
}
////////////////////////////////////////////////////////
void ZFT::OnMouseMove(UINT nFlags, CPoint point)
{//OnMouseMove函数处理鼠标消息,显示当前鼠标所在直方图上的灰度值等信息;
 CWnd *pWnd,*pWndText;//定义两个窗口对象;
 CPoint point1;//定义个一个点对象;
 point1=point;//存放当前鼠标的位置信息;
 CRect rect;//矩形对象;
 CString string ;//字符串对象;
 pWnd=GetDlgItem(IDC_Graphic);//得到显示直方图的框架窗口对象指针;
 pWndText=GetDlgItem(IDC_NUM);//得到指向文本框对象(IDC_NUM)窗口的指针;
 pWnd->GetWindowRect(&rect);//获取pWnd窗口对象窗口区域位置;
 file://屏幕坐标转换为客户区坐标;
 ScreenToClient(&rect);
 file://判断当前鼠标是否指在直方图内;
 if(rect.PtInRect (point))
 {
  int x=point1.x-rect.left;
  file://当前鼠标位置减去区域的起始位置恰好为当前鼠标所指位置所表示的灰度级;
  string.Format("%d",x);
  file://显示当前位置对应的图像的灰度级;
  pWndText->SetWindowText((LPCTSTR)string);
 }
 CDialog::OnMouseMove(nFlags, point);
}
////////////////////////////////////////
void CDibView::OnImagehorgm()
file://在程序的"视"类对象内处理显示图像直方图的函数;
{
 CDibDoc *pDoc=GetDocument();
 HDIB hdib;
 hdib=pDoc->GetHDIB();
 BITMAPINFOHEADER *lpDIBHdr;//位图信息头结构指针;
 BYTE *lpDIBBits;//指向位图像素灰度值的指针;
 lpDIBHdr=( BITMAPINFOHEADER *)GlobalLock(hdib);//得到图像的位图头信息
 lpDIBBits=(BYTE*)lpDIBHdr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
 file://获取图像像素值
 ZFT dialog;//直方图对话框模板对象;
 int i,j;
 int wImgWidth=lpDIBHdr->biWidth;
 int wImgHeight=lpDIBHdr->biHeight;
 file://a[]数组用来存放各个灰度级出现的概率;
 float a[256];
 for(i=0;i<256;i++)//初始化数组;
 {  
  a[i]=0;
 }
 file://统计各个灰度级出现的次数;
 for(i=0;i  {
  for(j=0;j   {
   a[*(lpDIBBits+WIDTHBYTES(wImgWidth*8)*i+j)]++;
  }
  file://统计各个灰度级出现的概率;
  for(i=0;i<256;i++)
  {
   a[i]=a[i]/(wImgHeight*wImgWidth);//得到每个灰度级的出现概率;
   memcpy(dialog.num,a,256*sizeof(float));
  }
 }
  dialog.DoModal();//显示直方图对话框;
 }
 return;
}


(a)LENA图像

(b)直方图
                     图一

  上图为LENA的原始图像和其对应的直方图,在(b)图中的135表示当前鼠标在直方图中所指的位置对应的灰度级为135。从该直方图可以看出,LENA图像的灰度主要分布在中高灰度级上,在低灰度级上图像的像素数几乎为零。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章