我正在使用opencv-python
中的Filter2D
函数,该图像的边缘有几个黑色填充值(零)。这里你可以找到我所说的一个例子:https://landsat.gsfc.nasa.gov/wp-content/uploads/2013/06/truecolor.jpg
当我在该图像上使用Filter2D
时,来自黑色填充区域的像素被视为有效值,从而产生边缘伪影。我怎么能不在计算中包括零呢?例如,在IDL中,我可以使用“missing”和“invalid”字段,如下所示:
output = CONVOL(input, kernel, /EDGE_TRUNCATE, MISSING=0.0, INVALID=0.0, /NAN, /NORMALIZE)
避免了边缘问题,但我在opencv中找不到类似的功能。如何解决这个问题?在
OpenCV函数中没有掩码或忽略参数。然而,唯一的伪影是图像的外部,即黑色区域。每当过滤器的锚定点(默认情况下,中间像素)位于边缘但位于黑色像素上时,它会将过滤结果添加到该像素。但是当定位点位于图像顶部时,黑色值不会向过滤器添加任何内容。所以,一个简单的解决方案是创建一个具有黑色值的遮罩,并从过滤后的图像中删除这些值。在
编辑:好,那么从IDL convol docs开始:
^{bq}$因此,从这里我们可以看到,通过将无效像素处理为0,然后通过除以不同于内核大小的像素数(即有效像素数)来偏移和。在
这在OpenCV中是不可能的,至少在内置的过滤方法中是不可能的,因为OpenCV不会规范化过滤结果。请看in the docs for ^{} 这个方程只是简单的相关性,没有除法。在
现在,您所能做的就是手动规范化。这并不难。如果您创建了一个掩码,其中值在正常图像内为1,在图像外部为0,那么具有与您的} 将在每个位置生成内核窗口内的像素计数。这是一种正常化图像的方法。然后您可以简单地屏蔽这个
filter2D()
相同内核大小的^{boxFilter()
结果,这样图像边界之外的值就会被忽略,最后,将您的filter2D()
结果除以屏蔽的boxFilter()
结果(忽略boxFilter()
结果是0的地方,这样就不会被零除)。那应该正是你想要的。在编辑2:这是一个具体的例子。首先,我将定义一个简单的图像(7x7,5x5内正方形为1s):
我们将继续使用一个简单的高斯核滤波示例:
^{pr2}$现在首先,过滤图像。。。在
这就是我们所期望的…一束1的高斯模糊度应该是,1s,然后我们在边缘有一些衰减,包括图像内部和外部的零区域。因此,我们将创建一个遮罩;在本例中,它与图像相同。然后在遮罩上做一个长方体过滤器,以获得正确的缩放值:
注意,如果您将其乘以9(内核中VAL的数量),那么我们将得到精确的“像素位置周围的非零像素数”。这是我们的标准化比例因子。现在要做的就是…规范化并移除图像边界之外的内容。在
现在这些值并不完美,但也不是有偏和。即使在IDL文档中也要注意:
所以你不能通过这样的缩放来获得完美的结果。但是,我们可以做得更好!我们使用的比例因子只使用点数,而不是每个点的实际权重。为此,我们可以用相关的权重过滤掩码。换句话说,只需在蒙版上运行
filter2D()
,而不是图像。显然,将图像除以此值只会将所有值转换为1;然后进行遮罩。我们完了!不要被这个例子搞糊涂了,因为蒙版和图像是一样的——在这种情况下,将过滤后的图像除以过滤后的遮罩得到1,但总的来说,这只是一个比框式过滤器更好的缩放比例。在这是一个进行均值滤波的示例,但可能适合您的问题:
亚历山大
首先,非常感谢您的详细解释和测试代码。我相信我理解您所使用的基本原理,并且我得出的代码似乎正是我所需要的:
产生:
^{pr2}$相关问题 更多 >
编程相关推荐