Scipy convolve2d和Theano' conv2d这样的子采样?

时间:2017-01-25 17:08:25

标签: python numpy scipy theano

我希望使用10 X 10滤镜对尺寸为600 X 400的图像进行2D卷积。过滤器不可分离。 scipy.signal.convolve2d目前适用于我,但我很快就会期待更大的图像。

为了解决这个问题,我有两个想法

  1. 调整图片大小
  2. 子采样(或跨步)?
  3. 关注子采样部分,theano有一个函数可以像scipy convolve2d那样进行卷积,参见theano conv2d

    它也有子采样选项。但是,在Windows上安装theano对我来说是痛苦的。如何使用scipy.signal.convolve2d进行子采样?还有其他选择(我不会要求我安装一些重量级的库)吗?

1 个答案:

答案 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]