【问题标题】:Calling filter functions from within a block-by-block processing function从逐块处理函数中调用过滤器函数
【发布时间】:2011-06-24 22:12:13
【问题描述】:

我有一些内存密集型图像过滤器,我想在大型图像/数组上逐块调用它们(因为它们会为整个数组计算过滤器,因此在尝试计算整个数组时会耗尽内存)。

def block_process(Ic, blocksize):
    B = numpy.empty(Ic.shape)

    colstart = 0
    while colstart < Ic.shape[1]:
        BlockWidth = blocksize
        if (colstart + blocksize) > Ic.shape[1]:
            BlockWidth = Ic.shape[1] - colstart
        rowstart = 0
        while rowstart < Ic.shape[0]:
            BlockHeight = blocksize
            if (rowstart + blocksize) > Ic.shape[0]:
                BlockHeight = Ic.shape[0] - rowstart

            B[colstart:colstart+BlockWidth, rowstart:rowstart+BlockHeight] = filter1(params) # One of many available filters

            rowstart += BlockHeight
        colstart += BlockWidth
    return B # The complete filtered array

我的过滤器是在其他函数中计算的,即def filter1(A, filtsize)def filter2(A, filtsize, otherparam),它们有一个A 参数(输入数组,由块函数给出)和其他参数,例如过滤器大小。一些过滤器的参数比其他过滤器多。他们返回过滤后的数组。

两个问题

  1. 如何通过 block_process 函数调用我的过滤器函数之一?我不想将块处理代码复制到每个函数中。换句话说,有没有一种方法可以指定调用哪个过滤器(以及使用哪些参数)作为block_process() 调用的参数?
  2. 有没有更好的编码方式?

【问题讨论】:

    标签: python image-processing workflow numpy


    【解决方案1】:

    你可以这样做:

    def block_process(a, blocksize, filt, args):
        b = numpy.empty(a.shape)
        for row in xrange(0, a.shape[0], blocksize):
            for col in xrange(0, a.shape[1], blocksize):
                b[row:row + blocksize, col:col + blocksize] = (
                    filt(a[row:row + blocksize, col:col + blocksize], *args))
        return b
    

    无需纠正图像右下边缘的不完整块——这将自动发生。您可以简单地传入过滤器函数和参数元组。要调用过滤器filter1(a, filtsize),请使用

    block_process(a, blocksize, filter1, (filtsize,))
    

    上面的代码假定过滤器的第一个参数是要过滤的数组,并且过滤器返回相同形状的过滤数组。

    您的过滤器也有可能被重写为不使用太多内存的方式,因此块处理将变得不必要。

    【讨论】:

    • 谢谢,太好了。我的过滤器在大型(5000x5000)数组上运行,需要在内存中保留 3-4 个相同大小的额外数组,这就是它们内存不足的原因,但这是另一个问题......
    • @Benjamin:通常需要的额外数组的数量可以减少——这可能确实是另一个问题:)
    • @Benjamin - 顺便说一句,分块做事的另一个好处是,使用multiprocessing 可以轻松地将计算分布到多个处理器上。因此,即使内存问题稍后得到修复,像这样分块也会很有用。
    • 简单线程通常也能正常工作,因为大多数计算密集型 NumPy 东西都在 GIL 之外运行。
    • @Joe Kington:如果你有兴趣,我已经发布了我的过滤器stackoverflow.com/questions/4959171/…
    猜你喜欢
    • 2018-09-09
    • 1970-01-01
    • 2021-11-29
    • 2019-06-26
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    相关资源
    最近更新 更多