处理大图像时的Python内存管理

时间:2018-11-07 19:55:30

标签: python image-processing memory-management

我是实施几个demosaicing algorithms for Python的软件包的维护者,并且用户报告处理7K图像时过多的内存使用。尽管在解决方案中我使用较少的并发进程,但在执行多处理时遇到了类似的问题。

例如,这是最令人讨厌的定义,其中保留了许多中间步骤,以便不会混淆代码,并且稍后还会重用某些代码。

def demosaicing_CFA_Bayer_Menon2007(CFA, pattern='RGGB', refining_step=True):
    CFA = np.asarray(CFA)
    R_m, G_m, B_m = masks_CFA_Bayer(CFA.shape, pattern)

    h_0 = np.array([0, 0.5, 0, 0.5, 0])
    h_1 = np.array([-0.25, 0, 0.5, 0, -0.25])

    R = CFA * R_m
    G = CFA * G_m
    B = CFA * B_m

    G_H = np.where(G_m == 0, _cnv_h(CFA, h_0) + _cnv_h(CFA, h_1), G)
    G_V = np.where(G_m == 0, _cnv_v(CFA, h_0) + _cnv_v(CFA, h_1), G)

    C_H = np.where(R_m == 1, R - G_H, 0)
    C_H = np.where(B_m == 1, B - G_H, C_H)

    C_V = np.where(R_m == 1, R - G_V, 0)
    C_V = np.where(B_m == 1, B - G_V, C_V)

    D_H = np.abs(C_H - np.pad(C_H, ((0, 0), (0, 2)),
                            mode=str('reflect'))[:, 2:])
    D_V = np.abs(C_V - np.pad(C_V, ((0, 2), (0, 0)),
                            mode=str('reflect'))[2:, :])

    k = np.array(
        [[0, 0, 1, 0, 1],
        [0, 0, 0, 1, 0],
        [0, 0, 3, 0, 3],
        [0, 0, 0, 1, 0],
        [0, 0, 1, 0, 1]])  # yapf: disable

    d_H = convolve(D_H, k, mode='constant')
    d_V = convolve(D_V, np.transpose(k), mode='constant')

    mask = d_V >= d_H
    G = np.where(mask, G_H, G_V)
    M = np.where(mask, 1, 0)

    # Red rows.
    R_r = np.transpose(np.any(R_m == 1, axis=1)[np.newaxis]) * np.ones(R.shape)
    # Blue rows.
    B_r = np.transpose(np.any(B_m == 1, axis=1)[np.newaxis]) * np.ones(B.shape)

    k_b = np.array([0.5, 0, 0.5])

    R = np.where(
        np.logical_and(G_m == 1, R_r == 1),
        G + _cnv_h(R, k_b) - _cnv_h(G, k_b), R)

    R = np.where(
        np.logical_and(G_m == 1, B_r == 1) == 1,
        G + _cnv_v(R, k_b) - _cnv_v(G, k_b), R)

    B = np.where(
        np.logical_and(G_m == 1, B_r == 1),
        G + _cnv_h(B, k_b) - _cnv_h(G, k_b), B)

    B = np.where(
        np.logical_and(G_m == 1, R_r == 1) == 1,
        G + _cnv_v(B, k_b) - _cnv_v(G, k_b), B)

    R = np.where(
        np.logical_and(B_r == 1, B_m == 1),
        np.where(M == 1, B + _cnv_h(R, k_b) - _cnv_h(B, k_b),
                B + _cnv_v(R, k_b) - _cnv_v(B, k_b)), R)

    B = np.where(
        np.logical_and(R_r == 1, R_m == 1),
        np.where(M == 1, R + _cnv_h(B, k_b) - _cnv_h(R, k_b),
                R + _cnv_v(B, k_b) - _cnv_v(R, k_b)), B)

    RGB = tstack((R, G, B))

    if refining_step:
        RGB = refining_step_Menon2007(RGB, tstack((R_m, G_m, B_m)), M)

    return RGB

用户提出了一个PR,其中随着过程的进行删除了中间步骤变量,并强行请求了垃圾回收。我自己从来没有走过这条路,因为我觉得那很简单,当您开始这样做时,很难在哪里停下来划清界限。无论如何,我希望该行为也可以选择加入,因为强制垃圾回收可能会引入其他性能问题。

鉴于上述情况,我想知道是否存在不这样做的替代方法,如果没有,是否可以编写一种可以一并处理删除和垃圾收集功能的方法。我看到的唯一障碍是可以通过自省实现将变量从其父范围中删除。

0 个答案:

没有答案