宽度W,高度H 的图像,做膨胀操作,如果膨胀的结构元素structure element,大小为kw,kh,那么就需要做W*H*kw*kh次运算,运算量比较大。
根据图像形态学的理论,膨胀满足结合律,即
,B和C为结构元素。假设一个结构元素S可以表示为两个结构元素B和C的膨胀,即S=B⊕C,则A⊕S=A⊕(B⊕C)=(A⊕B)⊕C,换言之,用S膨胀A等同于用B先膨胀A,再用C膨胀前面的结果。我们称S能够分解成B和C两个结构元素。结合律很重要,因为计算膨胀所需要的时间正比于结构元素中的非零像素的个数。通过上述推导,分解结构元素,然后再分别用子结构元素进行膨胀操作往往会实现很客观的速度的增长。
同样,腐蚀也可以做结构分解,腐蚀满足公式
,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)
代码如下
1
#include <cv.h>
2
#include <highgui.h>
3
#include <stdio.h>
4
5
6
int main(int argc, char** argv)
7

{
8
if(argc<2)
{
9
printf("has no param\n");
10
return 0;
11
}
12
13
IplConvKernel *element1 = cvCreateStructuringElementEx( 1, 25, 0, 0, CV_SHAPE_RECT, 0);
14
IplConvKernel *element2 = cvCreateStructuringElementEx( 16, 1, 0, 0, CV_SHAPE_RECT, 0);
15
IplConvKernel *element3 = cvCreateStructuringElementEx( 16, 25, 0, 0, CV_SHAPE_RECT, 0);
16
17
IplImage* src=cvLoadImage(argv[1],1);
18
19
20
if( src!= NULL)
21
{
22
23
IplImage* img = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
24
cvCvtColor(src,img,CV_BGR2GRAY);
25
cvReleaseImage(&src);
26
27
28
IplImage* tmp = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
29
cvDilate( img, tmp, element1, 1);
30
31
IplImage* dst1 = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
32
cvDilate( tmp, dst1, element2, 1);
33
34
35
IplImage* dst2 = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
36
cvDilate( img, dst2, element3, 1);
37
38
IplImage* diff = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
39
cvSub(dst2,dst1,tmp,NULL);
40
cvEqualizeHist( tmp, diff);
41
cvReleaseImage(&tmp);
42
43
int noZeroCount=cvCountNonZero(diff);
44
printf("no zerocount %d\n",noZeroCount);
45
46
47
cvNamedWindow("img",CV_WINDOW_AUTOSIZE);
48
cvShowImage("img",img);
49
cvNamedWindow("dst1",CV_WINDOW_AUTOSIZE);
50
cvShowImage("dst1",dst1);
51
cvNamedWindow("dst2",CV_WINDOW_AUTOSIZE);
52
cvShowImage("dst2",dst2);
53
cvNamedWindow("diff",CV_WINDOW_AUTOSIZE);
54
cvShowImage("diff",diff);
55
56
57
cvWaitKey();
58
cvDestroyAllWindows();
59
60
61
cvReleaseImage(&img);
62
cvReleaseImage(&dst1);
63
cvReleaseImage(&dst2);
64
cvReleaseImage(&diff);
65
66
cvReleaseStructuringElement(&element1);
67
cvReleaseStructuringElement(&element2);
68
cvReleaseStructuringElement(&element3);
69
70
71
72
73
74
}
75
else
76
{
77
printf("error,not load\n");
78
}
79
return 0;
80
};
81