在逐块处理函数中调用过滤函数
我有一些占用内存比较多的图像滤镜,我想在处理大图像或大数组时,分块调用这些滤镜(因为它们是针对整个数组计算滤镜的,当试图计算整个数组时会耗尽内存)。
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
参数(输入数组,由分块函数提供),还有其他参数,比如滤镜的大小。有些滤镜的参数比其他的多。它们会返回处理过的数组。
两个问题
- 我该如何通过
block_process
函数调用我的某个滤镜函数?我不想把分块处理的代码复制到每个函数里。换句话说,有没有办法在调用block_process()
时指定要调用哪个滤镜(以及用什么参数)? - 有没有更好的编码方式?
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,))
上面的代码假设过滤器的第一个参数是要过滤的数组,并且过滤器会返回一个形状相同的过滤后数组。
还有一种可能是,你的过滤器可以改写成使用更少的内存,这样就不需要进行块处理了。