问题描述
来自我的锻炼说明:
二维高斯可以通过一维高斯与其转置的卷积形成。
这是我的一维高斯函数:
def gauss1d(sigma,filter_length=11):
# INPUTS
# @ sigma : sigma of gaussian distribution
# @ filter_length : integer denoting the filter length
# OUTPUTS
# @ gauss_filter : 1D gaussian filter without normalization
rng = range(-int(filter_length/2),int(filter_length/2)+1)
gauss_filter = [np.exp((-x**2) / (2*sigma**2)) for x in rng]
# The formula used above has been given in the instruction.
return np.array(gauss_filter)
以及在图像和过滤器之间执行 2D 卷积的 2d 卷积函数,图像是 2D 图像。
def myconv2(image,filt):
# INPUTS
# @ image : 2D image,as numpy array of size mxn
# @ filt : 1D or 2D filter of size kxl
# OUTPUTS
# img_filtered : 2D filtered image,of size (m+k-1)x(n+l-1)
m,n = image.shape
k,l = filt.shape
offsety = k // 2
offsetx = l // 2
img_filtered = np.zeros((m+k-1,n+l-1),"double")
image = np.pad(image,((offsety,offsety),(offsetx,offsetx)),mode='constant')
for i in range(offsety,m+offsety):
for j in range(offsetx,n+offsetx):
Box_vals = image[ i - offsety : i + offsety+1,j-offsetx: j+offsetx+1]
new_val = np.sum( filt * Box_vals)
img_filtered[i][j] = np.sum(new_val)
return img_filtered
函数如何适用于 5x5 输入图像和 3x3 滤波器内核的简单演示:
sigma = 3
filter_length = 5
gauss = gauss1d(sigma,filter_length).reshape(1,filter_length)
guass
array([[0.18073067,0.20897821,0.22058223,0.18073067]])
gauss_t = np.transpose(gauss)
gauss_t
array([[0.18073067],[0.20897821],[0.22058223],[0.18073067]])
myconv2(gauss,guass_t)
array([[0.,0.,0. ],[0.,[0.03986597,0.04609688,0.04865652,0.03986597],0. ]])
正如你所看到的,它实际上不是一个二维高斯核,并且缺少一些值。 我不知道我缺少什么以及我应该在代码中考虑什么才能达到目标。 谢谢。
解决方法
你可以做一个矩阵乘法。卷积也应该有效,只是要注意填充。
gaus2d = gauss.T @ gauss
您的 conv2d 实现似乎不正确。我建议您实施“有效”卷积(或互相关):
simple_valid_cross_correlation(img,filt):
ih,iw = img.shape
fh,fw = filt.shape
result = np.zeros((ih - fh + 1,iw - fw + 1))
for i in range(result.shape[0]):
for j in range(result.shape[1]):
result[i,j] = np.sum(filt * img[i:i+fh,j:j+fw])
return result
gauss_pad = np.pad(gauss.T,((0,0),(gauss.shape[1]-1,gauss.shape[1]-1)))
gauss2d = simple_valid_cross_correlation(gauss_pad,gauss)
如果您不想实现自己的转化,还有 scipy.signal.convolve2d
。我觉得可能会更快