我正在做一些关于在Python中卷积图像的事情,为了速度,我选择了opencv 2.4.9.
Opencv提供了一种名为filter2D的方法来执行此操作,这里是它的文档:http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlightlight = filter2d#filter2d
在文档中,它说:
用内核卷积图像.
但我有疑问(由别的东西引起)所以我做了一些实验:
首先,我做一个正常的3x3矩阵一个使用numpy的是:
[[ 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上的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
这个结果是正确的.
步骤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.
(有人可能会对渐变与转换之间的差异感到困惑.似乎卷积在方向上向右和向下扩展图像,而左右方向相关.)
但这不是重点.
第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的真实情况吗?非常感谢.
如果您在OpenCV文档的说明中进一步阅读:
该函数实际上计算相关性,而不是卷积:
也就是说,内核不会在锚点周围镜像.如果你需要一个真正的卷积,请使用翻转内核
flip()
并将新锚设置为(kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)
.