我在带有图像 m 的 matlab 中使用 imerode 和 imdilate
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
有人可以向我解释吗?
非常感谢。
我在带有图像 m 的 matlab 中使用 imerode 和 imdilate
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
有人可以向我解释吗?
非常感谢。
当将结构元素应用于不存在的值时会发生此工件(例如,它可能发生在边界处,或者在您的情况下使用排除中心的 1x1 结构元素)。
在这种情况下,MATLAB'simerode
和imdilate
yield-Inf
和Inf
分别。
您可以在此处阅读更多内容以了解此现象。
要理解这个问题,需要先了解腐蚀和膨胀运算符。这些操作的典型概括是作为局部最小和最大过滤器(其中结构元素(SE)或内核选择要过滤的元素)。
对于一个由真实元素组成的 3x3 平方的 SE,侵蚀通过找到该元素与其所有 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 是“空的”并且没有真正的元素时会发生什么?如果图像中没有元素从哪里计算最小值怎么办?您的用例,即 just 的 SE 0
,非常具体,因为它根本没有任何真正的元素。侵蚀操作需要计算一个空集的最小值。空集的最小值是多少?
octave> imerode (im, [0])
ans =
Inf Inf Inf Inf
Inf Inf Inf Inf
Inf Inf Inf Inf
Inf Inf Inf Inf
答案没有多大意义。但也没有操作,即空集的最小值。但是,Matlab 究竟是如何得到这个奇怪的答案的Inf
呢?
Inf
and的结果-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
如果您查看定义此操作的理论论文,通常在连续区间(而不是离散区间)中,您会发现它指的是上确界和下确界,其结果是-Inf
和+Inf
对于空集,而不是最大值和最小值。因此,这取决于您在定义膨胀和腐蚀时是否使用上确界和下确界,而不是最大值和最小值。这也取决于你是否接受空集的上确界和下确界是-Inf
和+Inf
。
Matlab 是否因此Inf
而-Inf
故意返回?我不知道,但我不会。他们的 imerode 和 imdilate 文档仅参考了 max 和 min 操作,最明显的实现(参见上面的伪代码)导致了这个结果。
我知道几年前我在实施 Octave时imdilate
并没有意识到这一点。imerode
如果您的图像没有 的值Inf
,则它们有两种方式显示为imdilate
和的结果imerode
。最终结果,Inf
价值观,可能看起来一样,但你获得它们的原因却完全不同。
这个问题所涉及的一种情况是,当您有一个“空白” SE 时,即没有真正元素的 SE。在这种情况下,您可以在图像的每个点计算空集的最小值。这与填充无关。没有填充,也没有任何缺失值。你得到 an 的原因Inf
是你并没有真正生成整组值然后找到它的最小值。您从一个值(Inf
可能的最大值)开始,然后与该集合中的下一个值进行比较。因为该集合本来是空的,所以永远不会进行比较,并最终得到初始值Inf
. 它解释了这一点:
octave> imerode (5, 0)
ans = Inf
另一种导致相同结果但与问题无关的情况是SE仅“挑选”图像之外的元素。这在 Mathworks 博客中解释了膨胀和腐蚀中的 Pad 值。理论上,腐蚀和膨胀操作忽略了边界外的元素(它们甚至不应该存在)。实际上,您确实会计算它们,因为忽略它们在计算上是昂贵的(从那时起,您需要知道您在图像中的位置并相应地调整 SE)。例如,如果您的 SE 是一个 3x3 正方形,并且您正在评估图像的左上角,则很难避免顶部和左侧超出边界的图像元素。所以 Matlab 用Inf
因为这些值不会影响 min 的结果。但只有当集合中有其他值可供选择时,这才是正确的。如果在图像中的任何点,所有 SE 都是边界外元素,那么您将计算Inf
仅来自填充的一组 s 的最小值。它解释了这一点:
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
0
实际上,如果这是您获得的输出,您实际上没有等效的结构元素 (SE) 。根据您的另一个问题Erose/Dilate image with zeros structuring element,这仅仅是对strel
Matlab 函数的滥用。
首先,让我们假设您实际上有一个 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
现在,如果您创建一个无效的 SEse = strel('arbitrary', 0)
并尝试使用形态运算符,我只能期待未定义的结果。Matlab 很好,给你一些东西看。