为什么用零结构元素侵蚀/扩张图像会导致( - )Inf值?

时间:2013-01-01 13:20:52

标签: matlab image-processing

我在matlab中使用imerode和imdilate with image m

0 0 0 
0 1 0
0 0 0 

和结构元素f

0

使用imerode的结果是

inf inf inf
inf inf inf
inf inf inf

和imdilate是

-inf -inf -inf
-inf -inf -inf
-inf -inf -inf

有人可以向我解释一下吗?
非常感谢你。

3 个答案:

答案 0 :(得分:1)

当在不存在的值上应用结构元素时会发生此工件(例如,它可能出现在边框处,或者在您的情况下通过使用排除中心的1x1结构元素)。
在这种情况下,MATLAB的imerodeimdilate分别产生-InfInf

您可以阅读更多here来澄清此现象。

答案 1 :(得分:0)

如果这是你得到的输出,你实际上没有一个等同于0的结构元素(SE)。根据您的另一个问题Erose/Dilate image with zeros structuring element,这仅仅是对Matlab中strel函数的误用。

首先,让我们假设您实际上是一个SE,它是一个独特的点0。对于侵蚀,这意味着您将在检查当前位置的强度和仅自身之间取最小值,因此除了当前位置的强度之外没有任何其他输出。扩张也是如此。要检查这一点,请验证描述侵蚀和扩张公式的任何正确文本。并且,在Matlab中:

f = [0 0 0; 0 1 0; 0 0 0]
se = strel('arbitrary', 1, 0)
imerode(f, se)

ans =

     0     0     0
     0     1     0
     0     0     0

imdilate(f, se)

ans =

     0     0     0
     0     1     0
     0     0     0

现在,如果您在se = strel('arbitrary', 0)中创建无效的SE并尝试使用形态运算符,我只能期望未定义的结果。 Matlab很好,给你一些东西可以看。

答案 2 :(得分:0)

要理解这个问题,需要在侵蚀和扩张操作员之下。这些操作的典型泛化是局部最小和最大过滤器(结构元素(SE)或内核选择要过滤的元素)。

用实例解释扩张和侵蚀

如果SE是3x3平方的真实元素,则侵蚀通过查找该元素与其所有8个邻居之间的最小值来计算每个图像元素的最小值:

octave> im
im =

   5   9   2   6
   8   5   8   1
   7   8   6   9
   8   4   8   1

octave> imerode (im, [1 1 1; 1 1 1; 1 1 1])
ans =

   5   2   1   1
   5   2   1   1
   4   4   1   1
   4   4   1   1

如果你将SE的中心元素设置为false,那么它会计算其所有8个邻居元素的最小值(注意它不包括它自己)。

octave> imerode (im, [1 1 1; 1 0 1; 1 1 1])
ans =

   5   2   1   1
   5   2   1   2
   4   4   1   1
   4   6   1   6

但是当你的SE“空”且没有真正的元素时会发生什么?如果图像中没有元素从哪里计算最小值怎么办?您的用例,仅为0的SE,非常具体,因为它根本没有任何真正的元素。侵蚀操作需要计算空集的最小值。空集的最小值是多少?

octave> imerode (im, [0])
ans =

   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf
   Inf   Inf   Inf   Inf

答案没有多大意义。但是操作也都没有,即空集的最小值。但是Matlab如何实际得到Inf的奇怪回答?

你怎么得到错误的答案?

Inf-Inf的结果(也发生在Octave中)是一个实现细节。由于Matlab是封闭源代码,我们无法确定它们是如何到达那里的,但是这里有一个伪代码可能的情况(它与Octave中发生的情况类似):

## pseudo-code for imerode (local-minimum) that may causes this issue
set eroded to image
for each element in image
    set MIN_VAL to +Inf
    for each value in element neighbourhood
        if value < MIN_VAL
            set MIN_VAL to value
    set eroded[element index] to MIN_VAL

这真的全部吗?我们真的不能用这样的SE来计算侵蚀和膨胀吗?

如果查看定义此操作的理论论文,通常在连续区间(而不是离散区间),您会发现它不是最大值和最小值,而是指supremum and infimum,其结果为-Inf and +Inf for empty sets。所以这取决于你在扩张和侵蚀的定义中使用上限和下限,而不是最大值和最小值。这也取决于你是否接受空集的上限和下限是-Inf+Inf

Matlab是否故意返回Inf-Inf?我不知道,但我不会。他们的imerode和imdilate文档只引用了max和min操作,最明显的实现(参见上面的伪代码)导致了这个结果。

我知道在几年前我为Octave实施imdilateimerode时我并没有意识到这一点。

关于填充值的其他答案和评论怎么样?

如果您的图片的值不是Inf,则有两种方式可以显示imdilateimerode的结果。最终结果Inf值可能看起来相同,但您获得它们的原因完全不同。

这个问题涉及的一种情况是,当你有一个“空白”SE时,即没有真正元素的SE。在这种情况下,在图像的每个点处计算空集的最小值。这与填充无关。没有任何填充,也没有任何缺失值。你得到Inf的原因是你没有真的生成整个值集,然后找到它的最小值。您从一个值(Inf,最大可能值)开始,然后与该集合中的下一个值进行比较。因为该集合是空的,所以永远不会进行比较,最终得到Inf的初始值。它解释了这一点:

octave> imerode (5, 0)
ans = Inf

另一种导致相同结果但与问题无关的情况是SE只在图像外“挑选”元素。 Mathworks博客Pad values in dilation and erosion对此进行了解释。理论上,侵蚀和扩张操作忽略了边界元素(它们甚至不应存在)。在实践中,你会计算它们,因为忽略它们在计算上是昂贵的(从那时起你需要知道图像中的位置并相应地调整SE)。例如,如果您的SE是3x3正方形,并且您正在评估图像的左上角,则很难避免顶部和左侧的边界外图像元素。因此,Matlab使用Inf填充图像,因为这些值不会影响min的结果。但只有在集合中有其他值来从中选择最小值时才会出现这种情况。如果在图像中的任何一点,所有SE都是边界外元素,那么您将计算仅来自填充的一组Inf的最小值。它解释了这一点:

octave> imerode (5, [1 1 1; 1 0 1; 1 1 1])
ans = Inf

octave> imerode (zeros (3), [0 0 0; 1 0 0; 1 1 0])
ans =

     0     0     0
     0     0     0
   Inf     0     0

octave> imerode (zeros (3), [0 0 0; 0 0 0; 1 1 1])
ans =

     0     0     0
     0     0     0
   Inf   Inf   Inf