所以我知道卷积具有交换/关联性质,而相关性没有,但从未真正写出一个简单的例子来测试这一点。(方程形式的证明在那里)
我只是在尝试这个简单的例子:
Image : [1 0 -1 0 1 0 1 1]
A kernel = [-1 0 1]
B kernel = [-1 0 1]
使用卷积,I * (a * b) 应该等于 (I * A) * B,但是当我尝试这样做时,它们并不相等......这让我很困惑。 有人能帮忙吗? 也许我在做计算时犯了一个人为错误......但它们应该是平等的,对吗?(假设边框被视为 0)
使用相关性,我理解的相同不应该相等......他们没有,但是,我的卷积也没有那么哈哈(但它应该!
任何帮助将不胜感激。
也 A*B(卷积)应该是 [0 -2 0] 对吧? 和 AxB(互相关)将是 [0 2 0]?
卷积运算符是可交换的。所以,你是对的,I*(A*B)
应该等于(I*A)*B
.让我们先将其转换为矩阵形成。核 A 的卷积可以转换为乘法由以下卷积矩阵 C :
C=
[-1 0 1 0 0 0 0 0]
[ 0 -1 0 1 0 0 0 0]
[ 0 0 -1 0 1 0 0 0]
[ 0 0 0 -1 0 1 0 0]
[ 0 0 0 0 -1 0 1 0]
[ 0 0 0 0 0 -1 0 1]
[ 1 0 0 0 0 0 -1 0]
[ 0 1 0 0 0 0 0 -1]
我们取内核 [-1 0 1] 并在第一行用 5 个零填充它。然后,下面的每一行都是前一行右侧 1 个位置的循环平移。 因此,如果我们想用 I 计算内核 A 的卷积:
I = [1 0 -1 0 1 0 1 1]
我们简单地计算矩阵向量乘法:
C*I^T
(其中 I^T 是转置向量)。
按照上述公式,我们得到:
I*(A*B) = (C*C)*I^T
计算 C*C,你会得到以下矩阵:
C^2=
[ 1 0 -2 0 1 0 0 0]
[ 0 1 0 -2 0 1 0 0]
[ 0 0 1 0 -2 0 1 0]
[ 0 0 0 1 0 -2 0 1]
[ 1 0 0 0 1 0 -2 0]
[ 0 1 0 0 0 1 0 -2]
[-2 0 1 0 0 0 1 0]
[ 0 -2 0 1 0 0 0 1]
和:
I*(A*B) = (C*C)*I^T =
[ 4]
[ 0]
[-2]
[ 1]
[ 0]
[-2]
[-2]
[ 1]
而(I*A)*B
在基质公式中C*(C*I^T)
等于基质结合性的I*(A*B)=(C*C)*I^T
。
您可以通过运行以下 numpy 代码来验证此结果:
import numpy as np
C = [[-1,0,1,0,0,0,0,0]]
for k in range(7):
C.append(np.roll(C[0],k+1))
C = np.array(C)
#print(C)
I = np.transpose(np.array([[1,0,-1,0,1,0,1,1]]))
print(f'C=n{C}n')
print(f'C^2=n{C@C}n')
print(f'(C*C)*I=n{(C@C)@I}n')
print(f' C*(C*I)=n{C@(C@I)}n')
运行上述代码的结果是:
C=
[[-1 0 1 0 0 0 0 0]
[ 0 -1 0 1 0 0 0 0]
[ 0 0 -1 0 1 0 0 0]
[ 0 0 0 -1 0 1 0 0]
[ 0 0 0 0 -1 0 1 0]
[ 0 0 0 0 0 -1 0 1]
[ 1 0 0 0 0 0 -1 0]
[ 0 1 0 0 0 0 0 -1]]
C^2=
[[ 1 0 -2 0 1 0 0 0]
[ 0 1 0 -2 0 1 0 0]
[ 0 0 1 0 -2 0 1 0]
[ 0 0 0 1 0 -2 0 1]
[ 1 0 0 0 1 0 -2 0]
[ 0 1 0 0 0 1 0 -2]
[-2 0 1 0 0 0 1 0]
[ 0 -2 0 1 0 0 0 1]]
(C*C)*I=
[[ 4]
[ 0]
[-2]
[ 1]
[ 0]
[-2]
[-2]
[ 1]]
C*(C*I)=
[[ 4]
[ 0]
[-2]
[ 1]
[ 0]
[-2]
[-2]
[ 1]]
因此,您可以看到获得了相同的结果。
请注意,A*B
不是 [0 -2 0] 而是 [1 0 -2 0 1],因为您取 A=[-1 0 1](两边的零垫,每边有 2 个零)并将其作为滑动窗口移动到 B=[-1 0 1] 上,所以首先你会得到:[-1-1, 0-1 +-1 0,-1 1+ 0 0 + 1-1, 1 0+0 1, 1 1] = [1 0 -2 0 1]。由此产生的 2 个宽度为 n 的内核的卷积长度为 2 n-1。