Calling filter functions from within a block-by-block processing function
I have some memory intensive image filters that I want to call block by block on large images/arrays (because they compute the filter for an entire array, they run out of memory when trying to compute the whole array).
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 f开发者_如何学编程ilters
rowstart += BlockHeight
colstart += BlockWidth
return B # The complete filtered array
My filters are computed in other functions i.e. def filter1(A, filtsize)
, def filter2(A, filtsize, otherparam)
, which have an A
parameter (the input array, given by the block function), and other parameters such as filter size. Some filters have more parameters than others. They return the filtered array.
Two questions
- How do I go about calling one of my filter functions through the block_process function? I don't want to copy the block processing code into each function. In other words, is there a way of specifying which filter to call (and with what parameters) as a parameter of the
block_process()
call? - Is there a better way of coding this?
You can do it like this:
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
There is no need to correct for incomplete blocks at the right and lower edge of the image -- this will happen automatically. You can simply pass in the filter function and the tuple of arguments. To call the filter filter1(a, filtsize)
, use
block_process(a, blocksize, filter1, (filtsize,))
The code above assumes that the first parameter to a filter is the array to be filtered and that a filter returns a filtered array of the same shape.
It is also possible that your filters can be rewritten in a way that they don't use as much memory, so the blockprocessing would become unnecessary.
精彩评论