使用卷积来导出图像边缘错误的结果
Using convolution in order to derive an image rise wrong results on the edges
我正在学习图像处理的在线课程,其中所有问题集都在 MATLAB 中给出。尽管如此,我试图用 Python 来解决它们,当我尝试使用以下内核的卷积计算图像导数时,我得到了一些意想不到的结果:[0.5,0, -0.5]
.
给定行 i
,我想使用与 g
的卷积来计算列导数。
image[i,:] = [1,2,3,4]
g = [0.5,0,-0.5]
我使用以下代码对两者进行了卷积:
inImage_i_conv = np.zeros_like(inImage_i)
for j in range(0,len(inImage_i)-1):
conv = []
for m in range(len(dy)):
l = m-1
conv.append(inImage_i[j-l]*dy[l+1])
inImage_i_conv[j] = np.sum(conv)
结果是array([-1, 1, 1, 0])
。
开头有-1
的原因是在j = 0
和l = 1
下,我实际上得到了[-1]
元素,它在Python 是第 n
个元素。
我应该在第 i
行之前添加一个 0
(或者相当于图像最左边一列的 0
列)吗?我应该在左边添加第一个元素的副本吗?
常见的做法是什么?因为我的结果显然是错误的。
所以如果你想自己纠正卷积,这里是一个好的开始。
import numpy as np
def zero_pad(X, pad):
X_pad = np.pad(X, pad, 'constant', constant_values=0)
return X_pad
def conv_step(x, W):
return np.sum(np.multiply(x, W))
def conv(s, k):
diff = abs(len(s) - len(k) - 1)
slide = len(k)
# flip kernel
k = k [::-1]
Z = np.zeros(shape=len(s)-diff)
for i in range(Z.shape[0]):
Z[i] = conv_step(s[i:i+slide], k)
return Z
s = [1,2,3,4]
g = [0.5,0,-0.5]
print(np.convolve(s, g, 'same')) # [ 1. 1. 1. -1.5]
print(conv(zero_pad(s,1),g)) # [ 1. 1. 1. -1.5]
您可以看到它returns 与built-in 函数np.convolve
相同。
它遵循卷积的基本步骤,您在 https://en.wikipedia.org/wiki/Convolution
中看到
- 将向量填充到所需的长度
- 翻转内核(或输入)
- 创建所需长度的fill-to向量
- 遍历它,每次先乘法再求和
我正在学习图像处理的在线课程,其中所有问题集都在 MATLAB 中给出。尽管如此,我试图用 Python 来解决它们,当我尝试使用以下内核的卷积计算图像导数时,我得到了一些意想不到的结果:[0.5,0, -0.5]
.
给定行 i
,我想使用与 g
的卷积来计算列导数。
image[i,:] = [1,2,3,4]
g = [0.5,0,-0.5]
我使用以下代码对两者进行了卷积:
inImage_i_conv = np.zeros_like(inImage_i)
for j in range(0,len(inImage_i)-1):
conv = []
for m in range(len(dy)):
l = m-1
conv.append(inImage_i[j-l]*dy[l+1])
inImage_i_conv[j] = np.sum(conv)
结果是array([-1, 1, 1, 0])
。
开头有-1
的原因是在j = 0
和l = 1
下,我实际上得到了[-1]
元素,它在Python 是第 n
个元素。
我应该在第 i
行之前添加一个 0
(或者相当于图像最左边一列的 0
列)吗?我应该在左边添加第一个元素的副本吗?
常见的做法是什么?因为我的结果显然是错误的。
所以如果你想自己纠正卷积,这里是一个好的开始。
import numpy as np
def zero_pad(X, pad):
X_pad = np.pad(X, pad, 'constant', constant_values=0)
return X_pad
def conv_step(x, W):
return np.sum(np.multiply(x, W))
def conv(s, k):
diff = abs(len(s) - len(k) - 1)
slide = len(k)
# flip kernel
k = k [::-1]
Z = np.zeros(shape=len(s)-diff)
for i in range(Z.shape[0]):
Z[i] = conv_step(s[i:i+slide], k)
return Z
s = [1,2,3,4]
g = [0.5,0,-0.5]
print(np.convolve(s, g, 'same')) # [ 1. 1. 1. -1.5]
print(conv(zero_pad(s,1),g)) # [ 1. 1. 1. -1.5]
您可以看到它returns 与built-in 函数np.convolve
相同。
它遵循卷积的基本步骤,您在 https://en.wikipedia.org/wiki/Convolution
- 将向量填充到所需的长度
- 翻转内核(或输入)
- 创建所需长度的fill-to向量
- 遍历它,每次先乘法再求和