opencv中的filter2D真的可以完成它的工作吗?

时间:2014-11-11 05:02:02

标签: python opencv correlation convolution

我正在做一些关于在Python中卷积图像的事情,为了速度,我选择了opencv 2.4.9。

Opencv提供了一种名为 filter2D 的方法来执行此操作,这里是其文档:http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d

在文档中,它说:

  

用内核包含图像。

但我怀疑(由别的东西引起)所以我做了一些实验:

首先,我使用numpy制作一个普通的3x3矩阵 a

  [[ 1.,  5.,  0.], 
   [ 7.,  2.,  9.], 
   [ 2.,  3.,  4.]]

然后,我将2x2矩阵 b 作为内核:

  

>>> b

  [[ 1.,  2.],
   [ 3.,  4.]]

最后,为了清楚地看到卷积关联之间的区别,请将 b 旋转180度并 b 看起来像:

  [[ 4.,  3.],
   [ 2.,  1.]]

现在,所有的前期工作都已完成。我们可以开始实验了。

步骤1.使用 scipy.ndimage.convolve ndconv = ndimage.convolve(a, b, mode = 'constant') ndconv

  [[ 35.,  33.,  18.],
   [ 41.,  45.,  44.],
   [ 17.,  24.,  16.]]

卷积操作 b 旋转180度,并使用 b < < / em>的。所以ndconv [0] [0] = 4 * 1 + 3 * 5 + 2 * 7 + 1 * 2 = 35,ndconv [2] [2] = 4 * 4 + 3 * 0 + 2 * 0 + 1 * 0 = 16

此结果正确

步骤2.使用 scipy.ndimage.correlate ndcorr = ndimage.correlate(a, b, mode = 'constant') ndcorr

  [[  4.,  23.,  15.],
   [ 30.,  40.,  47.],
   [ 22.,  29.,  45.]]

根据相关性的定义, ndcorr [0] [0] = 1 * 0 + 2 * 0 + 3 * 0 + 4 * 1 = 4因为边界将扩展 0

(有人可能会因为扩展与conv和corr之间的差异而感到困惑。 似乎卷入向右和向下方向展开图片,而关联在方向左上方。)

但这不是重点。

步骤3.使用 cv2.filter2D cvfilter = cv2.filter2D(a, -1, b) cvfilter

  [[ 35.,  34.,  35.],
   [ 41.,  40.,  47.],
   [ 33.,  29.,  45.]]

如果我们忽略边界情况,我们会发现 cv2.filter2D 所做的实际上是一个相关而不是卷积!我该怎么说呢?

  

因为 cvfilter [1..2] [1..2] == ndcorr [1..2] [1..2]

WEIRD,不是吗?

任何人都可以告诉 cv2.filter2D 的真实情况吗?非常感谢。

2 个答案:

答案 0 :(得分:7)

如果您在OpenCV documentation

的说明中进一步了解
  

该函数确实计算了相关性,而不是卷积:

     

OpenCV filter2d() formula

     

也就是说,内核不会在锚点周围镜像。如果您需要真正的卷积,请使用flip()翻转内核并将新锚设置为(kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)

答案 1 :(得分:1)

嗯,我觉得OpenCV也是如此。如果你想根据数字图像处理理论进行真正的卷积,你应该在应用cv2.filter2D之前手动反转内核。