我正在做一些关于在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.]]
卷积op将b旋转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.filter2D:cvfilter = 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所做的真实事情吗?谢谢。
我认为OpenCV是这样的。如果要根据数字图像处理理论进行真正的卷积,则应在应用
cv2.filter2D
之前手动反转内核。如果您在OpenCV documentation中的描述中进一步阅读:
相关问题 更多 >
编程相关推荐