加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

图像形态学膨胀 结构元素

(2013-12-02 16:35:20)
标签:

it

分类: opencv

转自:http://www.cppblog.com/mcs51a/archive/2013/02/21/197971.html

 

宽度W,高度H 的图像,做膨胀操作,如果膨胀的结构元素structure element,大小为kw,kh,那么就需要做W*H*kw*kh次运算,运算量比较大。

根据图像形态学的理论,膨胀满足结合律,即http://www.cppblog.com/images/cppblog_com/mcs51a/dilation_satisfies.png结构元素" />,B和C为结构元素。假设一个结构元素S可以表示为两个结构元素B和C的膨胀,即S=B⊕C,则A⊕S=A⊕(B⊕C)=(A⊕B)⊕C,换言之,用S膨胀A等同于用B先膨胀A,再用C膨胀前面的结果。我们称S能够分解成B和C两个结构元素。结合律很重要,因为计算膨胀所需要的时间正比于结构元素中的非零像素的个数。通过上述推导,分解结构元素,然后再分别用子结构元素进行膨胀操作往往会实现很客观的速度的增长。

同样,腐蚀也可以做结构分解,腐蚀满足公式 http://www.cppblog.com/images/cppblog_com/mcs51a/erosion_satisfies.png结构元素" />,B和C为结构元素,同样如果一个结构元素S可以表示为两个结构元素B和C的膨胀,即S=B⊕C,那么用S腐蚀A等同于用B先腐蚀A,再用C腐蚀前面的结果。公式推导省略。

图像形态学膨胀和腐蚀介绍,可见
http://en.wikipedia.org/wiki/Erosion_(morphology)
http://en.wikipedia.org/wiki/Dilation_(morphology)


做结构分解后的运算量为W*H*(kw+kh)


代码如下

1http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />#include <</SPAN>cv.h>
2http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />#include <</SPAN>highgui.h>
3http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />#include <</SPAN>stdio.h>
4http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />
5http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />
6http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />int main(int argc, char** argv)
7http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif结构元素" TITLE="图像形态学膨胀 结构元素" /> if(argc<</SPAN>2) http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> printf("has no param\n");
10http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> return 0;
11http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif结构元素" /> }

12http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
13http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplConvKernel *element1 = cvCreateStructuringElementEx( 1, 25, 0, 0, CV_SHAPE_RECT, 0);
14http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplConvKernel *element2 = cvCreateStructuringElementEx( 16, 1, 0, 0, CV_SHAPE_RECT, 0);
15http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplConvKernel *element3 = cvCreateStructuringElementEx( 16, 25, 0, 0, CV_SHAPE_RECT, 0);
16http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
17http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplImage* src=cvLoadImage(argv[1],1);
18http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
19http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
20http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> if( src!= NULL)
21http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif结构元素" TITLE="图像形态学膨胀 结构元素" /> {
22http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
23http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplImage* img = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
24http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvCvtColor(src,img,CV_BGR2GRAY);
25http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseImage(&src);
26http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
27http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
28http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplImage* tmp = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
29http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvDilate( img, tmp, element1, 1);
30http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
31http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplImage* dst1 = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
32http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvDilate( tmp, dst1, element2, 1);
33http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
34http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
35http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplImage* dst2 = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
36http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvDilate( img, dst2, element3, 1);
37http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
38http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> IplImage* diff = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
39http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvSub(dst2,dst1,tmp,NULL);
40http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvEqualizeHist( tmp, diff);
41http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseImage(&tmp);
42http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
43http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> int noZeroCount=cvCountNonZero(diff);
44http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> printf("no zerocount %d\n",noZeroCount);
45http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
46http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
47http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvNamedWindow("img",CV_WINDOW_AUTOSIZE);
48http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvShowImage("img",img);
49http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvNamedWindow("dst1",CV_WINDOW_AUTOSIZE);
50http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvShowImage("dst1",dst1);
51http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvNamedWindow("dst2",CV_WINDOW_AUTOSIZE);
52http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvShowImage("dst2",dst2);
53http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvNamedWindow("diff",CV_WINDOW_AUTOSIZE);
54http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvShowImage("diff",diff);
55http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
56http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
57http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvWaitKey();
58http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvDestroyAllWindows();
59http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
60http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
61http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseImage(&img);
62http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseImage(&dst1);
63http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseImage(&dst2);
64http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseImage(&diff);
65http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
66http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseStructuringElement(&element1);
67http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseStructuringElement(&element2);
68http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> cvReleaseStructuringElement(&element3);
69http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
70http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
71http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
72http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
73http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" />
74http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif结构元素" /> }

75http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> else
76http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif结构元素" TITLE="图像形态学膨胀 结构元素" /> {
77http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> printf("error,not load\n");
78http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif结构元素" /> }

79http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif结构元素" /> return 0;
80http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif结构元素" />}
;
81http://www.cppblog.com/Images/OutliningIndicators/None.gif结构元素" />

 

http://blog.csdn.net/yeqiu712/article/details/6388263

在OpenCV中,定义了一个结构用于描述形态学中的结构元素。该结构定义如下:

typedef struct _IplConvKernel

{

int nCols;

int nRows;

int anchorX;

int anchorY;

int *values;

int nShiftR;

}

IplConvKernel;

在这里,对其中的变量定义做一简单的描述:

nCols,nRows:结构元素的行宽与列高;

anchorX,anchorY:结构元素原点(锚点)的位置坐标,水平,垂直;

nShiftR:用于表示结构元素的形状类型,有如下几个值:

#define CV_SHAPE_RECT 0

#define CV_SHAPE_CROSS 1

#define CV_SHAPE_ELLIPSE 2

#define CV_SHAPE_CUSTOM 100

分别表示矩形,十字,椭圆和自定义。

values:当nShiftR为自定义时,value是指向结构元素数据的指针,如果结构元素的大小定义为8*6,那么values为48长的int数组,值为0或1。

 

在OpenCV中定义了两个关于结构元素IplConvKernel的操作,用于结构元素的创建和释放。

cvCreateStructuringElementEx
创建结构元素
IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchor_x, int anchor_y,
int shape, int* values=NULL );
cols 结构元素的列数目
rows 结构元素的行数目
anchor_x 锚点的相对水平偏移量
anchor_y 锚点的相对垂直偏移量
shape 结构元素的形状,可以是下列值:
CV_SHAPE_RECT, 长方形元素;
CV_SHAPE_CROSS, 交错元素 a cross-shaped element;
CV_SHAPE_ELLIPSE, 椭圆元素;
CV_SHAPE_CUSTOM, 用户自定义元素。这种情况下参数 values 定义了 mask,即象素的那个邻域必须考虑。
values 指向结构元素的指针,它是一个平面数组,表示对元素矩阵逐行扫描。(非零点表示该点属于结构元)。如果指针为空,则表示平面数组中的所有元素都是非零的,即结构元是一个长方形(该参数仅仅当shape参数是 CV_SHAPE_CUSTOM 时才予以考虑)。
函数 cv CreateStructuringElementEx 分配和填充结构 IplConvKernel, 它可作为形态操作中的结构元素。

 

cvReleaseStructuringElement 删除结构元素
void cvReleaseStructuringElement( IplConvKernel** element );
element 被删除的结构元素的指针
函数 cvReleaseStructuringElement 释放结构 IplConvKernel 。如果 *element 为 NULL, 则函数不作用。

其他结构元素的扩展操作参见:

http://lh2078.blog.163.com/blog/static/56811372201051891044624/

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有