opencv形态学处理

来源:互联网 发布:科胜通软件 编辑:程序博客网 时间:2024/05/18 16:54
一、图像腐蚀 膨胀 细化的基本原理

1.图像细化的基本原理
⑴ 图像形态学处理的概念
数字图像处理中的形态学处理是指将数字形态学作为工具从图像中提取对于表达和描绘区域形状有用处的图像分量,比如边界、骨架以及凸壳,还包括用于预处理或后处理的形态学过滤、细化和修剪等。图像形态学处理中我们感兴趣的主要是二值图像。
在二值图像中,所有黑色像素的集合是图像完整的形态学描述,二值图像的各个分量是Z2的元素。假定二值图像A和形态学处理的结构元素B是定义在笛卡儿网格上的集合,网格中值为1的点是集合的元素,当结构元素的原点移到点(x,y)时,记为Sxy,为简单起见,结构元素为3x3,且全都为1,在这种限制下,决定输出结果的是逻辑运算。

⑵ 二值图像的逻辑运算
逻辑运算尽管本质上很简单,但对于实现以形态学为基础额图像处理算法是一种有力的补充手段。在图像处理中用到的主要逻辑运算是:与、或和非(求补),它们可以互相组合形成其他逻辑运算。

⑶ 膨胀和腐蚀
膨胀和腐蚀这两种操作是形态学处理的基础,许多形态学算法都是以这两种运算为基础的。
① 膨胀
是以得到B的相对与它自身原点的映像并且由z对映像进行移位为基础的。A被B膨胀是所有位移z的集合,这样, 和A至少有一个元素是重叠的。我们可以把上式改写为:
结构元素B可以看作一个卷积模板,区别在于膨胀是以集合运算为基础的,卷积是以算术运算为基础的,但两者的处理过程是相似的。
⑴ 用结构元素B,扫描图像A的每一个像素
⑵ 用结构元素与其覆盖的二值图像做“与”操作
⑶ 如果都为0,结果图像的该像素为0。否则为1

② 腐蚀
对Z中的集合A和B,B对A进行腐蚀的整个过程如下:
⑴ 用结构元素B,扫描图像A的每一个像素
⑵ 用结构元素与其覆盖的二值图像做“与”操作
⑶ 如果都为1,结果图像的该像素为1。否则为0
腐蚀处理的结果是使原来的二值图像减小一圈。

⑷ 击中(匹配)或击不中变换
假设集合A是由3个子集X,Y和Z组成的集合,击中(匹配)的目的是要在A中找到X的位置,我们设X被包围在一个小窗口W中,与W有关的X的局部背景定义为集合的差(W-X),则X在A内能得到精确拟合位置集合是由X对A的腐蚀后由(W-X)对A的补集Ac腐蚀的交集,这个交集就是我们要找的位置,我们用集合B来表示由X和X的背景构成的集合,我们可以令B=(B1,B2),这里B1=X,B2=(W-X),则在A中对B进行匹配可以表示为:
A⊙B
我们称为形态学上的击中或击不中变换。



⑸ 开闭操作
开操作是先腐蚀、后膨胀处理。

闭操作是先膨胀、后腐蚀处理。



(6) 细化
图像细化一般作为一种图像预处理技术出现,目的是提取源图像的骨架,即是将原图像中线条宽度大于1个像素的线条细化成只有一个像素宽,形成“骨架”,形成骨架后能比较容易的分析图像,如提取图像的特征。
细化基本思想是“层层剥夺”,即从线条边缘开始一层一层向里剥夺,直到线条剩下一个像素的为止。图像细化大大地压缩了原始图像地数据量,并保持其形状的基本拓扑结构不变,从而为文字识别中的特征抽取等应用奠定了基础。细化算法应满足以下条件:
① 将条形区域变成一条薄线;
② 薄线应位与原条形区域的中心;
③ 薄线应保持原图像的拓扑特性。
细化分成串行细化和并行细化,串行细化即是一边检测满足细化条件的点,一边删除细化点;并行细化即是检测细化点的时候不进行点的删除只进行标记,而在检测完整幅图像后一次性去除要细化的点。
常用的图像细化算法有hilditch算法,pavlidis算法和rosenfeld算法等。

注:进行细化算法前要先对图像进行二值化,即图像中只包含“黑”和“白”两种颜色。

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #include <stdlib.h>  
  4. #include <stdio.h>  
  5. IplImage* src = 0;  
  6. IplImage* dst = 0;  
  7. IplConvKernel* element = 0;  
  8. int element_shape = CV_SHAPE_RECT;  
  9. //the address of variable which receives trackbar position update   
  10. int max_iters = 10;  
  11. int open_close_pos = 0;  
  12. int erode_dilate_pos = 0;  
  13. // callback function for open/close trackbar  
  14. void OpenClose(int pos)     
  15. {  
  16.     int n = open_close_pos - max_iters;  
  17.     int an = n > 0 ? n : -n;  
  18.     element = cvCreateStructuringElementEx( an*2+1, an*2+1, an, an, element_shape, 0 );  
  19.     if( n < 0 )  
  20.     {  
  21.         cvErode(src,dst,element,1);  
  22.         cvDilate(dst,dst,element,1);  
  23.     }  
  24.     else  
  25.     {  
  26.         cvDilate(src,dst,element,1);  
  27.         cvErode(dst,dst,element,1);  
  28.     }  
  29.     cvReleaseStructuringElement(&element);  
  30.     cvShowImage("Open/Close",dst);  
  31. }    
  32. // callback function for erode/dilate trackbar  
  33. void ErodeDilate(int pos)     
  34. {  
  35.     int n = erode_dilate_pos - max_iters;  
  36.     int an = n > 0 ? n : -n;  
  37.     element = cvCreateStructuringElementEx( an*2+1, an*2+1, an, an, element_shape, 0 );  
  38.     if( n < 0 )  
  39.     {  
  40.         cvErode(src,dst,element,1);  
  41.     }  
  42.     else  
  43.     {  
  44.         cvDilate(src,dst,element,1);  
  45.     }  
  46.     cvReleaseStructuringElement(&element);  
  47.     cvShowImage("Erode/Dilate",dst);  
  48. }    
  49.   
  50. int main( int argc, char** argv )  
  51. {  
  52.     char* filename = argc == 2 ? argv[1] : (char*)"baboon.jpg";  
  53.     if( (src = cvLoadImage(filename,1)) == 0 )  
  54.         return -1;  
  55.     printf( "Hot keys: \n"  
  56.         "\tESC - quit the program\n"  
  57.         "\tr - use rectangle structuring element\n"  
  58.         "\te - use elliptic structuring element\n"  
  59.         "\tc - use cross-shaped structuring element\n"  
  60.         "\tENTER - loop through all the options\n" );  
  61.     dst = cvCloneImage(src);  
  62.     //create windows for output images  
  63.     cvNamedWindow("Open/Close",1);  
  64.     cvNamedWindow("Erode/Dilate",1);  
  65.     open_close_pos = erode_dilate_pos = max_iters;  
  66.     cvCreateTrackbar("iterations""Open/Close",&open_close_pos,max_iters*2+1,OpenClose);  
  67.     cvCreateTrackbar("iterations""Erode/Dilate",&erode_dilate_pos,max_iters*2+1,ErodeDilate);  
  68.     for(;;)  
  69.     {  
  70.         int c;  
  71.           
  72.         OpenClose(open_close_pos);  
  73.         ErodeDilate(erode_dilate_pos);  
  74.         c = cvWaitKey(0);  
  75.         if( (char)c == 27 )  
  76.             break;  
  77.         if( (char)c == 'e' )  
  78.             element_shape = CV_SHAPE_ELLIPSE;  
  79.         else if( (char)c == 'r' )  
  80.             element_shape = CV_SHAPE_RECT;  
  81.         else if( (char)c == 'c' )  
  82.             element_shape = CV_SHAPE_CROSS;  
  83.         else if( (char)c == '\n' )  
  84.             element_shape = (element_shape + 1) % 3;  
  85.     }  
  86.     //release images  
  87.     cvReleaseImage(&src);  
  88.     cvReleaseImage(&dst);  
  89.     //destroy windows   
  90.     cvDestroyWindow("Open/Close");   
  91.     cvDestroyWindow("Erode/Dilate");  
  92.     return 0;  
  93. }  



原创粉丝点击