openCv学习笔记(五)-数学形态学2(灰度级膨胀和腐蚀及c语言实现)

本文介绍了灰度级图像的膨胀和腐蚀操作,通过顶面和本影的概念阐述基本原理,并提供了C语言实现这两种操作的代码示例。程序处理256级灰度图像,只关注黑点,对黑点进行膨胀或腐蚀操作,改变其周围像素以达到图像处理效果。
摘要由CSDN通过智能技术生成

一 基本概念

     所谓的灰度级膨胀和腐蚀即将而知图像的二值形态学运算推广到灰度图像上。对于一幅图像的腐蚀(膨胀)运算定义为对每个像素赋值为某个领域内输入图像灰度级的最小(或最大值)。在二值变换中的结构元素只代表一个领域,而在灰度级变化中,结构元素是一个二元函数,它规定了希望的局部灰度级性质。在求的邻域内最大值(或最小值)的同时,将结构元素的值相加(相减)。

   以下的灰度级运算将从数学的角度描述。这里引进两个概念。即本影和顶面函数

  考虑一个n维欧式空间中的点集A(即一幅灰度图像)。并假定前(n-1)个坐标构成一个空间定义域(像素点坐标),而第n个坐标轴表示某点的函数值(对于灰度图像来说,n=3)。简单的说就是集合A为三维矩阵,其中点由坐标的三元表示,前两元表示像素的坐标,第三个元表示高度,即像素的亮度。

   1.1集合A的顶面:为定义在(n-1)维底面上的函数,对于每个(n-1)元祖来书,顶面就是A最后一个坐标的最高值。(个人理解:把灰度级理解为假象地貌中某个位置的海拔高度,顶面就是海拔高度函数)。

   1.2顶面函数f的本影:本影的一般定义为,一个不透明物体遮挡光线而形成的完全阴影区域,在数学形态学中,函数f的本影定义为一个由f的顶面及其下所有点构成的集合。

二 灰度级腐蚀和膨胀

    2.1 灰度级腐蚀

       基本步骤:(1)计算它们的本影 (2)对本影采用二值腐蚀 (3)计算顶面即为结果

    2.2灰度级膨胀

       基本步骤:(1)计算它们的本影 (2)对本影采用二值膨胀 (3)计算顶面即为结果

    以上只要理解好了本影就好了。对于灰度级的腐蚀和膨胀理解要借助一些图形,这里主要参考(MilanSonka 、Valav Hlavac、Roger Boyle 图像处理、分析与机器视觉(第三版) 十三章)

三 C语言实现(摘自百度文库)

    具体的文档可在资源里下载http://download.csdn.net/detail/caiye917015406/4460983

下面的这段程序,实现了上述的腐蚀运算,针对的都是黑色点。参数中有一个BOOL变量,为真时,表示在水平方向进行腐蚀运算,即结构元素B;否则在垂直方向上进行腐蚀运算,即结构元素B

BOOLErosion(HWND hWnd,BOOL Hori)

{

      DWORD                            OffBits,BufSize;

LPBITMAPINFOHEADER   lpImgData;

      LPSTR                  lpPtr;

      HLOCAL                 hTempImgData;

      LPBITMAPINFOHEADER    lpTempImgData;

      LPSTR                          lpTempPtr;

      HDC                     hDc;

      HFILE                   hf;

      LONG                   x,y;

      unsigned char             num;

      int                       i;

//为了处理方便,仍采用256级灰度图,不过只用调色板中0255两项

if(NumColors!=256){ 

          MessageBox(hWnd,"Must be a monobitmap with grayscale palette!",

"ErrorMessage",MB_OK|MB_ICONEXCLAMATION);

return FALSE;

}

OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);

//BufSize为缓冲区大小

      BufSize=OffBits+bi.biHeight*LineBytes;

      //为新的缓冲区分配内存

      if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)

{

           MessageBox(hWnd,"Erroralloc memory!","Error Message",

MB_OK|MB_ICONEXCLAMATION);

return FALSE;

   }

    lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);   

      lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);

      //拷贝头信息和位图数据    

      memcpy(lpTempImgData,lpImgData,BufSize);

      if(Hori)

      {  

//在水平方向进行腐蚀运算

             for(y=0;y<bi.biHeight;y++){

                    //lpPtr指向原图数据,lpTempPtr指向新图数据

                    lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;

                    lpTempPtr=(char*)lpTempImgData+

(BufSize-LineBytes-y*LineBytes)+1;

                    for(x=1;x<bi.biWidth-1;x++){

//注意为防止越界,x的范围从1到宽度-2

                           num=(unsigned char)*lpPtr;

                           if (num==0){  //因为腐蚀掉的是黑点,所以只对黑点处理

                                  *lpTempPtr=(unsigned char)0;  //先置成黑点

                                  for(i=0;i<3;i++){

                                         num=(unsigned char)*(lpPtr+i-1);

                                         if(num==255){

//自身及上下邻居中若有一个不是黑点,则将该点腐

//蚀成白点

                                                *lpTempPtr=(unsigned char)255;

                                                break;

                                         }

                                  }

                           }

//原图中就是白点的,新图中仍是白点

                           else *lpTempPtr=(unsigned char)255; 

                           //指向下一个象素

                           lpPtr++;

                           lpTempPtr++;

                    }

             }

      }

else{

//在垂直方向进行腐蚀运算

             for(y=1;y<bi.biHeight-1;y++){ //注意为防止越界,y的范围从1到高度-2

                    //lpPtr指向原图数据,lpTempPtr指向新图数据

                    lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值