版权声明:本文为博主原创文章,转载请告诉我下,我高兴高兴~ https://blog.csdn.net/u012851419/article/details/78026596 </div>
<div id="content_views" class="markdown_views">
<!-- flowchart 箭头图标 勿删 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg>
<p><img src="https://img-blog.csdn.net/20170919152558134?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjg1MTQxOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描述" title=""> </p>
写这个帖子的原因是在学习灰度图像处理中,发现没有一个博客很系统全面的讲解这些形态学变换,所以为了帮助后来人,特此做此工作,但是能力有限,如果有不对的地方请大家多多批评指正!另外有一些前辈的工作在里面,在后面我会给出引用。
灰度图像与二值图像的形态学变换不尽相同,形态学处理的定义与二值图像有些不同,因为二值图像可以用一系列的二维坐标来表示图像信息,而灰度图需要一个三维坐标表示,而且二值图像中结构元SE是平坦的,没有灰度信息的,但灰度图中,结构元是可以带有第三维信息的,即结构元也是灰度的,这就带来了一些问题,因为二值图像中,形态学的输出结果完全由输入图像产生,但是结构元一旦引入灰度信息,那么输出结果将不再由输入图像唯一确定。所以,一般情况下,结构元都使用平坦的结构元。
腐蚀与膨胀
是形态学的基本操作,在灰度图像中也是如此,在二值图像中腐蚀和膨胀定义为对图像进行translation以后的“与”和“或”的逻辑操作结果,在灰度图像中,为了保存灰度信息,“与”和“或”操作被对应的替换成了“最大值”和“最小值”操作这样就给出了灰度图像中腐蚀和膨胀的操作定义。
直接看矩阵中的操作吧,简单明了。
腐蚀
膨胀
开操作与闭操作
与二值图像中的定义相同,开、闭操作也又腐蚀膨胀操作衍生出来的,依旧先腐蚀后膨胀是开操作,先膨胀后腐蚀是闭操作。
开操作
闭操作
顶帽和低帽变换
这两个变换在翻译的时候有不同的叫法,但是不用管这些啦,毕竟都是一个意思嘛。 顶帽操作和底帽操作是灰度图像所特有 的,其原理是开操作将使峰顶消去,具体消去了多少呢,可以用原图减去开操作结果,这样就能得到其消去的部分,而这个过程成为顶帽操作,顶帽就是开操作消去的峰顶,这一部分对应于图像中较亮的部分,也叫白色顶帽。
开运算放大了裂缝或者局部低亮度的区域,所以,从原图中减去开运算后的图,得到的结果突出了比原图轮廓周围的区域更明亮的区域,这个操作与选择的核的大小有关。TopHat运算一般用来分离比邻近点亮一些的斑块,可以使用这个运算提取背景。
同理,底帽操作是用闭操作的结果减去原图就得到被闭操作填充的谷底部分,这一部分对应于图像中较暗的部分,也叫黑色底帽。黑帽运算的结果突出了比原图轮廓周围区域更暗的区域,所以黑帽运算用来分离比邻近点暗一些的斑块。
顶帽
低帽
测地腐蚀与测地膨胀
测地腐蚀与测地膨胀在二值图像中的操作是将腐蚀与膨胀结果与ground做“与”和“或”操作,与灰度膨胀中膨胀的推广一样,“与”和“或”被取代为最大值和最小值。
void lhMorpRErode(const IplImage* src, const IplImage* msk, IplImage* dst, IplConvKernel* se = NULL , int iterations=-1 )
{
assert(src != NULL && msk != NULL && dst != NULL && src != dst );
if (iterations < 0 )
{
cvMax(src, msk, dst);
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
IplImage* temp1 = cvCreateImage(cvGetSize(src), 8 , 1 );
IplImage* temp2 = cvCreateImage(cvGetSize(src), 8 , 1 );
do
{
cvCopy(dst, temp1);
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
cvCmp(temp1, dst, temp2, CV_CMP_NE);
}
while (cvSum(temp2).val [0 ] != 0 );
cvReleaseImage(&temp1);
cvReleaseImage(&temp2);
return ;
}
else if (iterations == 0 )
{
cvCopy(src, dst);
}
else
{
cvMax(src, msk, dst);
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
for (int i=1 ; i<iterations; i++)
{
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
http://blog.csdn.net/TonyShengTan/article/details/42426033
版权声明:本文为博主原创文章,转载请告诉我下,我高兴高兴~ https://blog.csdn.net/u012851419/article/details/78026596 </div>
<div id="content_views" class="markdown_views">
<!-- flowchart 箭头图标 勿删 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg>
<p><img src="https://img-blog.csdn.net/20170919152558134?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjg1MTQxOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="这里写图片描述" title=""> </p>
写这个帖子的原因是在学习灰度图像处理中,发现没有一个博客很系统全面的讲解这些形态学变换,所以为了帮助后来人,特此做此工作,但是能力有限,如果有不对的地方请大家多多批评指正!另外有一些前辈的工作在里面,在后面我会给出引用。
灰度图像与二值图像的形态学变换不尽相同,形态学处理的定义与二值图像有些不同,因为二值图像可以用一系列的二维坐标来表示图像信息,而灰度图需要一个三维坐标表示,而且二值图像中结构元SE是平坦的,没有灰度信息的,但灰度图中,结构元是可以带有第三维信息的,即结构元也是灰度的,这就带来了一些问题,因为二值图像中,形态学的输出结果完全由输入图像产生,但是结构元一旦引入灰度信息,那么输出结果将不再由输入图像唯一确定。所以,一般情况下,结构元都使用平坦的结构元。
腐蚀与膨胀
是形态学的基本操作,在灰度图像中也是如此,在二值图像中腐蚀和膨胀定义为对图像进行translation以后的“与”和“或”的逻辑操作结果,在灰度图像中,为了保存灰度信息,“与”和“或”操作被对应的替换成了“最大值”和“最小值”操作这样就给出了灰度图像中腐蚀和膨胀的操作定义。
直接看矩阵中的操作吧,简单明了。
腐蚀
膨胀
开操作与闭操作
与二值图像中的定义相同,开、闭操作也又腐蚀膨胀操作衍生出来的,依旧先腐蚀后膨胀是开操作,先膨胀后腐蚀是闭操作。
开操作
闭操作
顶帽和低帽变换
这两个变换在翻译的时候有不同的叫法,但是不用管这些啦,毕竟都是一个意思嘛。 顶帽操作和底帽操作是灰度图像所特有 的,其原理是开操作将使峰顶消去,具体消去了多少呢,可以用原图减去开操作结果,这样就能得到其消去的部分,而这个过程成为顶帽操作,顶帽就是开操作消去的峰顶,这一部分对应于图像中较亮的部分,也叫白色顶帽。
开运算放大了裂缝或者局部低亮度的区域,所以,从原图中减去开运算后的图,得到的结果突出了比原图轮廓周围的区域更明亮的区域,这个操作与选择的核的大小有关。TopHat运算一般用来分离比邻近点亮一些的斑块,可以使用这个运算提取背景。
同理,底帽操作是用闭操作的结果减去原图就得到被闭操作填充的谷底部分,这一部分对应于图像中较暗的部分,也叫黑色底帽。黑帽运算的结果突出了比原图轮廓周围区域更暗的区域,所以黑帽运算用来分离比邻近点暗一些的斑块。
顶帽
低帽
测地腐蚀与测地膨胀
测地腐蚀与测地膨胀在二值图像中的操作是将腐蚀与膨胀结果与ground做“与”和“或”操作,与灰度膨胀中膨胀的推广一样,“与”和“或”被取代为最大值和最小值。
void lhMorpRErode(const IplImage* src, const IplImage* msk, IplImage* dst, IplConvKernel* se = NULL , int iterations=-1 )
{
assert(src != NULL && msk != NULL && dst != NULL && src != dst );
if (iterations < 0 )
{
cvMax(src, msk, dst);
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
IplImage* temp1 = cvCreateImage(cvGetSize(src), 8 , 1 );
IplImage* temp2 = cvCreateImage(cvGetSize(src), 8 , 1 );
do
{
cvCopy(dst, temp1);
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
cvCmp(temp1, dst, temp2, CV_CMP_NE);
}
while (cvSum(temp2).val [0 ] != 0 );
cvReleaseImage(&temp1);
cvReleaseImage(&temp2);
return ;
}
else if (iterations == 0 )
{
cvCopy(src, dst);
}
else
{
cvMax(src, msk, dst);
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
for (int i=1 ; i<iterations; i++)
{
cvErode(dst, dst, se);
cvMax(dst, msk, dst);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
http://blog.csdn.net/TonyShengTan/article/details/42426033