我是图像处理的新手。在矩阵上应用下面的左移内核确实会将结果矩阵左移一步。
matrix=np.array([[0,1,2],
[3,4,5],
[6,7,8]])
kernel=np.array([[0,0,0],
[1,0,0],
[0,0,0]])
结果:
[[1 2 0]
[4 5 0]
[7 8 0]]
我觉得奇怪的是,如果我“手动”将实际的卷积算法应用到矩阵,结果似乎应该向右移动 1 步...要看到这一点,请取矩阵的中心元素'4':在其上应用左移内核意味着该单元格的卷积结果应为 0*0 + 0*1 + 0*2 + 1*3++ 0*4 + 0*5 + 0*6 + 0*7 + 0*8 == 3,也就是左边相邻格子的‘3’向右移动……
我在这里错过了什么?
[编辑]:在 Hivert 的回答之后,为了理解它,根据我之前对矩阵操作约定的理解,我实现了自己的“卷积”:
import numpy as np
import scipy.ndimage.filters as filter
def neighbors(r,c,supermatrix):
m = supermatrix[r:r+3,c:c+3]
return m
def convolve(n,kernel):
sum = 0
for (rr,cc),value in np.ndenumerate(n):
sum += value * kernel[rr,cc]
return sum
matrix = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
kernel = np.array([[0,0,0],
[0,0,0],
[0,0,1]])
print 'matrix'
print matrix
print 'kernel'
print kernel
print 'result'
print filter.convolve(matrix,kernel,mode='constant', cval=0)
shape = matrix.shape
# create a 'supermatrix' surrounding the real matrix
# with the borders with zeroes
# insert the real matrix into the center of supermatrix
newshape =(shape[0] + 2,shape[1] + 2)
sm = np.zeros(newshape,dtype=np.int)
sm[1:-1,1:-1] = matrix
result = np.zeros(shape,dtype=np.int)
for (r,c),value in np.ndenumerate(matrix):
n = neighbors(r,c,sm)
result[r,c] = convolve(n,kernel)
print 'poor mans convolve'
print result
这段代码产生了一个真实卷积函数的“镜像”结果,也就是说,如果我将恒等核向左移动,那么这段代码会将图像向右移动,而真正的卷积函数将向左移动和 vv。
因此,区别在于惯例。关于公约为何如此的任何想法?
最佳答案
您对卷积的定义可能有错误的约定。计算res[i,j]
的公式是
res[i,j] = sum_{k,l} matrix[k,l] kernel[i-(k-1), j-(l-1)]
注意 k-1
和 l-1
是为了将内核的 center 视为 (0,0)协调。因此
res[1,1] = m[0,0]k[2,2] + m[1,0]k[1,2] + ...
这给出了预期的结果。
关于python - 与 Scipy : shifted identity kernel - how is the computation done? 的图像卷积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21679878/