形态运算中的迭代与内核大小(OpenCV)

pyh*_*hat 5 opencv image-morphology

我一直在使用变形.开在OpenCV中,以降低噪声通过我的OpenCV的图像中ROI之外,直到现在,每当我需要更高程度的降噪我只是随机增加内核的大小或增加迭代次数,直到我很高兴.但结果是否存在显着差异,具体取决于您增加的数量/在给定情况下您将如何决定改变哪些?我试图想出一个更好的方法来改变我所改变的参数(除了猜测和检查).

alk*_*asm 11

这取决于内核类型.对于使用奇数平方内核进行扩张或侵蚀,无论是增大大小还是增加迭代都没有区别(假设使用了使它们相等的值).例如:

>>> M = np.zeros((7,7), dtype=np.uint8)
>>> M[3,3] = 1

>>> k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
>>> M1 = cv2.dilate(M, k1, iterations=2)

>>> k2 = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
>>> M2 = cv2.dilate(M, k2, iterations=1)

>>> M1
[[0 0 0 0 0 0 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 0 0 0 0 0 0]]

>>> M2
[[0 0 0 0 0 0 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 1 1 1 1 1 0]
 [0 0 0 0 0 0 0]]
Run Code Online (Sandbox Code Playgroud)

这非常直观.3x3用于扩张的矩形内核将找到任何白色像素,并将相邻像素变为白色.所以很容易看出,这样做两次会使任何一个白色像素变成一个5x5的白色像素块.这里我们假设中心像素是被比较的那个--- ---但这可能会改变,这可能会影响结果.例如,假设您将(2, 2)内核的两次迭代与内核的单次迭代进行比较(3, 3):

>>> M = np.zeros((5, 5), dtype=np.uint8)
>>> M[2,2] = 1

>>> k1 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
>>> M1 = cv2.dilate(M, k1, iterations=2)

>>> k2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
>>> M2 = cv2.dilate(M, k2, iterations=1)

>>> M1
[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 1 1 1]
 [0 0 1 1 1]
 [0 0 1 1 1]]

>>> M2
[[0 0 0 0 0]
 [0 1 1 1 0]
 [0 1 1 1 0]
 [0 1 1 1 0]
 [0 0 0 0 0]]
Run Code Online (Sandbox Code Playgroud)

您可以看到,虽然它创建了形状(直观),但它们并不在同一个地方(非直观).这是因为(2, 2)内核的锚不能位于内核的中心 - 在这种情况下我们看到,对于居中的像素,扩张的邻居只是右下角,因为它必须选择一个方向,因为它只能扩展单个像素以填充(2, 2)正方形.

对于非矩形的内核,事情变得更加棘手.例如:

>>> M = np.zeros((5, 5), dtype=np.uint8)
>>> M[2,2] = 1

>>> k1 = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
>>> M1 = cv2.dilate(M, k1, iterations=2)

>>> k2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
>>> M2 = cv2.dilate(M, k2, iterations=1)

>>> M1
[[0 0 1 0 0]
 [0 1 1 1 0]
 [1 1 1 1 1]
 [0 1 1 1 0]
 [0 0 1 0 0]]

>>> M2
[[0 0 1 0 0]
 [0 0 1 0 0]
 [1 1 1 1 1]
 [0 0 1 0 0]
 [0 0 1 0 0]]
Run Code Online (Sandbox Code Playgroud)

M1的第一次传递产生一个3像素高的小十字形,宽3像素.但是这些像素中的每一个都会在它们的位置创建一个十字形,这实际上会创建一个菱形图案.

因此,总结基本的形态学操作,矩形内核,至少是奇数维的,结果是相同的 - 但对于其他内核,结果是不同的.您可以将其他形态学操作应用于这样的简单示例,以了解它们的行为方式以及您应该使用哪些以及如何增加它们的效果.