我希望使用10 X 10滤镜在尺寸为600 X 400的图像上执行2D卷积。过滤器不可分离。 scipy.signal.convolve2d
目前对我来说效果很好,但是我希望很快会有更大的图像。
为了解决这个问题,我有两个想法
调整图像大小
二次采样(或大步)?
专注于子采样部分,theano具有与scipy convolve2d相同的卷积功能,请参见theano conv2d
它还具有子采样选项。但是,在Windows上安装theano对我来说很痛苦。如何使用scipy.signal.convolve2d
进行二次采样?还有其他选择(不需要我安装一些重量级的库)吗?
最佳答案
您可以手工实现子采样,为简单起见,我仅绘制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进行子采样。对所有偏移量总计为0或k的子采样d和f进行卷积,然后将结果相加。
这是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]
关于python - Scipy像Theano的conv2d一样通过二次采样进行卷积?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41857498/