在逐块处理函数中调用过滤函数

0 投票
1 回答
914 浏览
提问于 2025-04-16 11:34

我有一些占用内存比较多的图像滤镜,我想在处理大图像或大数组时,分块调用这些滤镜(因为它们是针对整个数组计算滤镜的,当试图计算整个数组时会耗尽内存)。

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. 有没有更好的编码方式?

1 个回答

2

你可以这样做:

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,))

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

还有一种可能是,你的过滤器可以改写成使用更少的内存,这样就不需要进行块处理了。

撰写回答