openCv对形态学的运算处理

一  首先要了解openCv里的核结构:IplConvKernel,以下如何创造

[cpp]  view plain copy
  1. IplConvKernel* cvCreateStructingElementEx(    
  2. int cols, //行   
  3. int rows,  //列  
  4. int anchor_x,  //核的封闭矩形内的参考点的坐标  
  5. int anchor_y,    
  6. int shape,  //CV_SHAPE_RECT:核是矩形,CV_SHAPE_CROSS:十字交叉形,CV_SHAPE_ELLIPSE:椭圆形,CV_SHAPE_CUSTOM:用户自定     义的值  
  7. int* values = null    
  8. );    


释放函数如下:

[cpp]  view plain copy
  1. void cvReleaseStructingElement(  
  2. IplConvKernel** element  
  3. );  


对于二值图像,可以用openCv里的cvErode和cvDilate来腐蚀和膨胀,

void cvDilate(//膨胀
IplImage* src,
IplImage* dst,
IplConvKernel* B = NULL,
int iterations = 1
);

void cvErode(//腐蚀
IplImage* src,
IplImage* dst,
IplConvKernel* B = NULL, //B即核,下同
int iterations = 1 //如名,迭代次数,下同
);

测试代码如下

[cpp]  view plain copy
  1. /******************************* 
  2. 数学形态运算,最常见的基本运算有七种, 
  3. 分别为:腐蚀、膨胀、开运算、闭运算、击中、细化和粗化, 
  4. 它们是全部形态学的基础。 
  5. ********************************/  
  6. #include "cv.h"  
  7. #include "highgui.h"  
  8. #include <stdlib.h>  
  9. #include <stdio.h>  
  10. IplImage *src=0;  
  11. IplImage *dst=0;  
  12. IplConvKernel *element=0;//声明一个结构元素  
  13.   
  14. int element_shape=CV_SHAPE_RECT;//长方形形状的元素  
  15. int max_iters=10;  
  16. int open_close_pos=0;  
  17. int erode_dilate_pos=0;  
  18. void OpenClose(int pos)  
  19. {  
  20.     int n=open_close_pos-max_iters;  
  21.     int an=n>0?n:-n;  
  22.     element = cvCreateStructuringElementEx(an*2+1,  
  23.     an*2+1,an,an,element_shape,0);//创建结构元素  
  24.     /* 
  25.    IplConvKernel* cvCreateStructingElementEx(   
  26.     int cols, //行  
  27.     int rows,  //列 
  28.     int anchor_x,  //核的封闭矩形内的参考点的坐标 
  29.     int anchor_y,   
  30.     int shape,  //CV_SHAPE_RECT:核是矩形,CV_SHAPE_CROSS:十字交叉形,CV_SHAPE_ELLIPSE:椭圆形,CV_SHAPE_CUSTOM:用户自定     义的值 
  31.     int* values = null   
  32.     );   
  33.  
  34. */  
  35.      
  36.     if (n<0)//开运算  
  37.     {  
  38.         cvErode(src,dst,element,1);//腐蚀图像  
  39.         cvDilate(dst,dst,element,1);//膨胀图像  
  40.         /* 
  41.         void cvDilate( 
  42.         IplImage* src, 
  43.         IplImage* dst, 
  44.         IplConvKernel* B = NULL,//默认的为3*3的核 
  45.         int iterations = 1    //迭代次数, 
  46.         ); 
  47.         */  
  48.     }  
  49.     else//闭运算  
  50.     {         
  51.         cvDilate(dst,dst,element,1);//膨胀图像  
  52.         cvErode(src,dst,element,1);//腐蚀图像  
  53.     }  
  54.     cvReleaseStructuringElement(&element);  
  55.     cvShowImage("Open/Close",dst);  
  56. }  
  57. void ErodeDilate(int pos)  
  58. {  
  59.     int n=erode_dilate_pos-max_iters;  
  60.     int an=n>0?n:-n;  
  61.     element = cvCreateStructuringElementEx(an*2+1,an*2+1,an,an,element_shape,0);  
  62.     if (n<0)  
  63.     {  
  64.         cvErode(src,dst,element,1);//腐蚀  
  65.     }  
  66.     else  
  67.     {  
  68.         cvDilate(src,dst,element,1);//膨胀  
  69.     }  
  70.     cvReleaseStructuringElement(&element);//释放核  
  71.     cvShowImage("Erode/Dilate",dst);  
  72. }  
  73. int main(int argc,char **argv)  
  74. {  
  75.     src = cvLoadImage("D:\\openCV\\openCVProject\\openCv笔记\\openCv笔记\\test.jpg");  
  76.     if(!src)  
  77.     {  
  78.         printf("open file error");  
  79.         return 0;  
  80.     }  
  81.     //菜单 参数介绍  
  82.     printf("参数:1.e-CV_SHAPE_ELLIPSE;2.r-CV_SHAPE_RECT,3./r-(element_shape+1)%3");  
  83.     dst=cvCloneImage(src);  
  84.     cvNamedWindow("Open/Close",1);  
  85.     cvNamedWindow("Erode/Dilate",1);  
  86.     open_close_pos = erode_dilate_pos = max_iters;  
  87.     cvCreateTrackbar("iterations","Open/Close",&open_close_pos,max_iters*2+1,OpenClose);  
  88.     cvCreateTrackbar("iterations","Erode/Dilate",&erode_dilate_pos,max_iters*2+1,ErodeDilate);  
  89.     for (;;)  
  90.     {  
  91.         int c;  
  92.         OpenClose(open_close_pos);  
  93.         ErodeDilate(erode_dilate_pos);  
  94.         c= cvWaitKey(0);  
  95.         if (c==27)  
  96.         {  
  97.             break;  
  98.         }  
  99.         switch(c) {  
  100.         case 'e':  
  101.             element_shape=CV_SHAPE_ELLIPSE;  
  102.             break;  
  103.         case 'r':  
  104.             element_shape=CV_SHAPE_RECT;  
  105.             break;  
  106.         case '/r':  
  107.             element_shape=(element_shape+1)%3;  
  108.             break;  
  109.         default:  
  110.             break;  
  111.         }  
  112.     cvReleaseImage(&src);  
  113.     cvReleaseImage(&dst);  
  114.      
  115.     cvDestroyWindow("Open/Close");  
  116.     cvDestroyWindow("Erode/Dilate");  
  117.     return 0;  
  118. }  
  119. /***************************** 
  120. 腐蚀和膨胀,看上去好像是一对互逆的操作,实际上,这两种操作不具有互逆的关系。 
  121. 开运算和闭运算正是依据腐蚀和膨胀的不可逆性,演变而来的。 
  122. 先腐蚀后膨胀的过程就称为开运算。 
  123. 闭运算是通过对腐蚀和膨胀的另一种不同次序的执行而得到的, 
  124. 闭运算是先膨胀后腐蚀的过程,其功能是用来填充物体内细小空洞、连接邻近物体、平滑其边界, 
  125. 同时不明显改变不明显改变其面积。 
  126. ******************************/  

二 但是对于灰度图或彩色图,不可以直接用cvErode和cvDilate来处理,这里需要更通用的函数,即cvMorphologyEx;

[cpp]  view plain copy
  1. cvMorphologyEx void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation,  int iterations=1 );   
  2.   src 输入图像.   
  3.   dst 输出图像.   
  4.   temp 临时图像,  
  5.   element 结构元素 operation 形态操作的类型:  
  6.               CV_MOP_OPEN - 开运算 CV_MOP_CLOSE - 闭运算   
  7.               CV_MOP_GRADIENT - 形态梯度   
  8.               CV_MOP_TOPHAT - "顶帽"   
  9.               CV_MOP_BLACKHAT - "黑帽"   
  10.               iterations 膨胀和腐蚀次数.   
  11.   函数 cvMorphologyEx 在膨胀和腐蚀基本操作的基础上,完成一些高级的形态变换:   
  12.          开运算 dst=open(src,element)=dilate(erode(src,element),element)   
  13.          闭运算 dst=close(src,element)=erode(dilate(src,element),element)   
  14.          形态梯度 dst=morph_grad(src,element)=dilate(src,element)-erode(src,element)   
  15.          "顶帽" dst=tophat(src,element)=src-open(src,element)   
  16.          "黑帽" dst=blackhat(src,element)=close(src,element)-src   
  17.          临时图像 temp 在形态梯度以及对“顶帽”和“黑帽”操作时的 in-place 模式下需要。  

注意:不推荐使用(摘自http://blog.csdn.net/shandianling/article/details/6423640)
  通过查看cvMorphologyEx的源代码,可以发现,在执行开、闭等运算,在进行第二步形态学腐蚀和膨胀时,该函数仍然采用与第一步相同的结构元素进行。这种方法在针对一般对称的结构元素情况是正确的,但是当结构元素为自定义的非对称结构元素时,结果图像会发生错误的偏移。 正确的方法是,如前面在开、闭运算的介绍中,执行第二步腐蚀、膨胀操作时,应采用结构元素的映射(反射)进行因此,在本文中不提倡使用cvMorphologyEx函数。

测试代码

[cpp]  view plain copy
  1. #include "StdAfx.h"  
  2. #include "cv.h"    
  3. #include "highgui.h"    
  4. #include "highgui.h"    
  5.   
  6. int main(int argc, char ** argv)    
  7. {    
  8.     cvNamedWindow("sourceImage");    
  9.     cvNamedWindow("open");    
  10.     cvNamedWindow("close");    
  11.     cvNamedWindow("gradient");   
  12.     cvNamedWindow("topHat");   
  13.     cvNamedWindow("blackHat");   
  14.     IplImage * src = cvLoadImage("test.bmp");    
  15.     cvShowImage("sourceImage",src);  
  16.     IplImage * temp = cvCreateImage(cvGetSize(src), 8,3);    
  17.     IplImage * img=cvCreateImage(cvGetSize(src), 8, 3);    
  18.     cvCopyImage(src,temp);    
  19.     cvCopyImage(src, img);    
  20.     //开运算    
  21.     cvMorphologyEx(    
  22.         src,    
  23.         img,    
  24.         temp,    
  25.         NULL, //default 3*3    
  26.         CV_MOP_OPEN,    
  27.         4);    
  28.     cvShowImage("open", img);    
  29.     //闭运算    
  30.     cvMorphologyEx(    
  31.         src,    
  32.         img,    
  33.         temp,    
  34.         NULL, //default 3*3    
  35.         CV_MOP_CLOSE,    
  36.         4);    
  37.     cvShowImage("close", img);    
  38.     //形态梯度    
  39.     cvMorphologyEx(    
  40.         src,    
  41.         img,    
  42.         temp,    
  43.         NULL, //default 3*3    
  44.         CV_MOP_GRADIENT,    
  45.         3);    
  46.     cvShowImage("gradient", img);    
  47.     //cvWaitKey(0);    
  48.   
  49.     //"礼帽"    
  50.     cvMorphologyEx(    
  51.         src,    
  52.         img,    
  53.         temp,    
  54.         NULL, //default 3*3    
  55.         CV_MOP_TOPHAT,    
  56.         3);    
  57.     cvShowImage("topHat", img);    
  58.     //cvWaitKey(0);    
  59.     //“黑帽”    
  60.     cvMorphologyEx(    
  61.         src,    
  62.         img,    
  63.         temp,    
  64.         NULL, //default 3*3    
  65.         CV_MOP_BLACKHAT,    
  66.         3);    
  67.     cvShowImage("blackHat", img);    
  68.     cvWaitKey(0);    
  69.     cvReleaseImage(&temp);    
  70.     cvReleaseImage(&src);    
  71.     cvReleaseImage(&img);    
  72.     cvDestroyAllWindows();    
  73.     return 0;    
  74. }   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值