我希望使用10 X 10滤镜对尺寸为600 X 400的图像进行2D卷积。过滤器不可分离。 scipy.signal.convolve2d
目前适用于我,但我很快就会期待更大的图像。
为了解决这个问题,我有两个想法
关注子采样部分,theano有一个函数可以像scipy convolve2d那样进行卷积,参见theano conv2d
它也有子采样选项。但是,在Windows上安装theano对我来说是痛苦的。如何使用scipy.signal.convolve2d
进行子采样?还有其他选择(我不会要求我安装一些重量级的库)吗?
答案 0 :(得分:1)
您可以手动实现子采样,为简单起见,我只会草拟1d。假设您要在间距为k的常规子网格上对s = d * f进行采样。然后你的第n个样本是s_nk = sum_i = 0 ^ 10 f_i d_nk-i。这里要注意的是f和d的索引总是加到k的倍数。这表明将其分成子和s_nk = sum_j = 0 ^ k-1 sum_i = 0 ^ 10 / k f_j + ik d_-j +(n-i)k。所以你需要做的是:在所有偏移0,...,k-1的间隔为k的网格上的子样本d和f。卷积所有子采样对d和f,其偏移量总和为0或k,并添加结果。
这里有一些1d的代码。它粗略地实现了上述内容,只是网格的放置略有不同,使索引管理更容易。第二个函数是愚蠢的方式,即计算完整的卷积然后抽取。它用于测试第一个函数。
import numpy as np
from scipy import signal
def ss_conv(d1, d2, decimate):
n = (len(d1) + len(d2) - 1) // decimate
out = np.zeros((n,))
for i in range(decimate):
d1d = d1[i::decimate]
d2d = d2[decimate-i-1::decimate]
cv = signal.convolve(d1d, d2d, 'full')
out[:len(cv)] += cv
return out
def conv_ss(d1, d2, decimate):
return signal.convolve(d1, d2, 'full')[decimate-1::decimate]
编辑:2d版本:
import numpy as np
from scipy import signal
def ss_conv_2d(d1, d2, decy, decx):
ny = (d1.shape[0] + d2.shape[0] - 1) // decy
nx = (d1.shape[1] + d2.shape[1] - 1) // decx
out = np.zeros((ny, nx))
for i in range(decy):
for j in range(decx):
d1d = d1[i::decy, j::decx]
d2d = d2[decy-i-1::decy, decx-j-1::decx]
cv = signal.convolve2d(d1d, d2d, 'full')
out[:cv.shape[0], :cv.shape[1]] += cv
return out
def conv_ss_2d(d1, d2, decy, decx):
return signal.convolve2d(d1, d2, 'full')[decy-1::decy, decx-1::decx]