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

2024-05-01 22:08:09 发布

您现在位置:Python中文网/ 问答频道 /正文

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

Opencv提供了一种名为filter2D的方法来实现这一点,这里是它的文档:http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d

在文档中,它说:

Convolves an image with the kernel.

但我有疑问(由其他原因引起),所以我做了一些实验:

首先,我用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.]]

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

第一步。使用scipy.ndimage.convalve:ndconv = ndimage.convolve(a, b, mode = 'constant')ndconv是:

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

卷积opb旋转180度,并在a上使用b进行相关操作。所以ndconv[0][0]=4*1+3*5+2*7+1*2=35,ndconv[2][2]=4*4+3*0+2*0+1*0=16

此结果是正确的。

第二步。使用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之间的膨胀差异搞糊涂。 似乎右下方向卷积展开图像,而左上方向相关

但这不是重点。

第三步。使用cv2.filter2Dcvfilter = cv2.filter2D(a, -1, b)cvfilter是:

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

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

because cvfilter[1..2][1..2] == ndcorr[1..2][1..2].

很奇怪,不是吗?

有人能说出cv2.filter2D所做的真实事情吗?谢谢。


Tags: 文档图像mode矩阵scipycv2opencv卷积
2条回答

我认为OpenCV是这样的。如果要根据数字图像处理理论进行真正的卷积,则应在应用cv2.filter2D之前手动反转内核。

如果您在OpenCV documentation中的描述中进一步阅读:

The function does actually compute correlation, not the convolution:

OpenCV filter2d() formula

That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip the kernel using flip() and set the new anchor to (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1).

相关问题 更多 >