形态运算中的迭代与内核大小的比较(OpenCV) [英] Iterations vs. Kernel Size in Morphological Operations (OpenCV)

查看:411
本文介绍了形态运算中的迭代与内核大小的比较(OpenCV)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用morph.在OpenCV中打开以通过opencv减少图像的投资回报率之外的噪声,直到现在,每当我需要更高程度的噪声降低时,我都只是随机增加内核大小或增加迭代次数,直到感到满意为止.但是,结果的显着不同取决于您增加的数量/在给定情况下如何决定要更改的内容?除了猜测并检查之外,我试图提供一种更好的方法来更改参数(改变多少).

I've been using morph. opening in OpenCV to reduce noise outside of my ROI in images via opencv, and until now, whenever I need a higher degree of noise reduction I just randomly increase kernel size or increase the number of iterations until I'm happy. But is there a significant difference in results depending on which you increase / how would you decide which to change in a given situation? I'm trying to come up with a better approach to which parameter I change (by how much) other than guess-and-check.

推荐答案

这取决于内核类型.对于使用奇方核进行膨胀或腐蚀,增加大小或增加迭代没有区别(假定使用使它们相等的值).例如:

It depends on the kernel type. For dilating or eroding with an odd-square kernel, there is no difference whether you increase the size or increase the iterations (assuming values which would make them equal are used). For example:

>>> 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]]

这是相当直观的.用于扩展的3x3矩形内核将找到任何白色像素,并将相邻像素变为白色.因此,很容易看到执行两次将使任何单个白色像素变成5x5的白色像素块.在这里,我们假设中心像素是被比较的像素- anchor -,但是可以更改,这可能会影响结果.例如,假设您正在比较(2, 2)内核的两个迭代与(3, 3)内核的单个迭代:

And this is fairly intuitive. A 3x3 rectangular kernel for dilating will find any white pixel, and turn the neighboring pixels white. So it's easy to see that doing this twice will make any single white pixel turn into a 5x5 block of white pixels. Here we're assuming the center pixel is the one that is compared---the anchor---but this could be changed, which could affect the result. For example, suppose you were comparing two iterations of a (2, 2) kernel with a single iteration of a (3, 3) kernel:

>>> 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]]

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

You can see that while it creates the shape (intuitive), they're not in the same place (non-intuitive). And that's because the anchor of a (2, 2) kernel cannot be in the center of the kernel---in this case we see that with a centered pixel, the neighbors that dilate are only to the bottom-right, since it has to choose a direction because it can only expand the single pixel to fill up a (2, 2) square.

使用非矩形内核时,事情变得更加棘手.例如:

Things become even more tricky with non-rectangular shaped kernels. For example:

>>> 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]]

M1的第一遍创建一个小十字,高3像素,宽3像素.但是,这些像素中的每个像素都会在其位置创建一个十字,实际上会创建菱形图案.

The first pass of M1 creates a small cross 3 pixels high, 3 pixels wide. But then each one of those pixels creates a cross at their location, which actually creates a diamond pattern.

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

So to sum up for basic morphological operations, with rectangular kernels, at least odd-dimensioned ones, the result is the same---but for other kernels, the result is different. You can apply the other morphological operations to simple examples like this to get a hang of how they behave and which you should be using and how to increase their effects.

这篇关于形态运算中的迭代与内核大小的比较(OpenCV)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆