在大型TIFF堆栈ndarray上对numpy / scipy样条进行优化吗?

时间:2018-08-09 16:31:48

标签: python numpy optimization scipy

所以我想从TIFF堆栈的 all 帧中删除 all 背景。基本上,我想为每帧每一行都适合一个样条线。

我知道,还有一些方法可以校正局部背景,以减少定位样本周围的幼稚背景“环”的开销,从而快速针对多个帧进行处理,以及进行某种形式的背景拟合(我听说过的用途)的速度非常慢)。

我的版本是这样:

import numpy as np
import time
from scipy.interpolate import UnivariateSpline as Spline

def timeit(method):
    times = []
    def timed(*args, **kw):
        ts = time.time()
        result = method(*args, **kw)
        te = time.time()
        times.append((te - ts) * 1000)
        print('%r  %2.2f ms' % (method.__name__, (te - ts) * 1000))
        return result
    return timed

# Generate something that resembles a video
img = np.random.randint(low = 0, high = 2**16, size = (10, 500, 400))
img = img/(2**16) # convert to (0,1)

@timeit
def spline_background_subtract(arr, deg, s):
    frames, rows, columns = arr.shape
    ix = np.arange(0, columns) # Points to evaluate spline over

    frames = []
    for i in range(img.shape[0]):
        frame = img[i, :, :]
        ls = [Spline(ix, frame[i, :], k = deg, s = s)(ix) for i in range(rows)]  # Fit every row with a spline to determine background
        new = np.row_stack(ls)  # Stack all rows
        frames.append(new)
    return frames

frames = spline_background_subtract(arr = img, deg = 2, s = 1e4)

# new_video = np.reshape(np.dstack(frames), newshape = (img.shape))

这在我的计算机上每帧大约需要50毫秒,但是如果我有1000帧和100部电影,那么如果应该实时进行校正,这很快就会加起来。

我试图尽可能地修剪它。除了用高性能语言重写所有内容之外,还有什么可以收获的东西?

编辑

一些测试:

  • scipy.interpolate.RectBivariateSpline大约慢一倍...
  • scipy.ndimage.filters.gaussian的速度大约是原来的两倍!如果要隔离的功能比较小(在我的情况下是这样),这将做得很好,因为它们会在较小的标准偏差下平滑化(=更快的计算速度)。

1 个答案:

答案 0 :(得分:0)

如果没有自己进行基准测试,我想这可能是罪魁祸首:

ls = [Spline(ix, frame[i, :], k = deg, s = s)(ix) for i in range(rows)]

如果可以向量化该操作,则可以加快速度。您也可以尝试使用类似2d bspline in scipy:的方法来加快速度。

还可以研究Cython / Numba