Python 3 的编织替代方案

4

我有一个函数来自这里,它使用了weave。有没有办法在不重写代码的情况下在Python 3中运行此代码?

代码:

def _thinningIteration(im, iter):
    I, M = im, np.zeros(im.shape, np.uint8)
    expr = """
    for (int i = 1; i < NI[0]-1; i++) {
        for (int j = 1; j < NI[1]-1; j++) {
            int p2 = I2(i-1, j);
            int p3 = I2(i-1, j+1);
            int p4 = I2(i, j+1);
            int p5 = I2(i+1, j+1);
            int p6 = I2(i+1, j);
            int p7 = I2(i+1, j-1);
            int p8 = I2(i, j-1);
            int p9 = I2(i-1, j-1);
            int A  = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) +
                     (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) +
                     (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) +
                     (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1);
            int B  = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
            int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8);
            int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8);
            if (A == 1 && B >= 2 && B <= 6 && m1 == 0 && m2 == 0) {
                M2(i,j) = 1;
            }
        }
    } 
    """

    weave.inline(expr, ["I", "iter", "M"])
    return (I & ~M)

当你尝试在Python 3中运行该代码时会发生什么?你会收到错误消息吗?如果是这样,你需要在你的问题中包含它。 - PM 2Ring
@PM2Ring ImportError: 无法导入名称 'weave' - max
1
啊,好的。我不使用SciPy,但是我刚刚发现了https://pypi.org/project/weave/,它说:“Weave是已弃用的Scipy子模块scipy.weave的独立版本。它仅适用于Python 2.x,并为需要新版本Scipy(其中可能会删除weave子模块)但仍依赖于scipy.weave的用户提供。对于新代码,建议用户使用Cython。”另请参阅https://github.com/scipy/weave,因此看起来您需要迁移到Cython。 - PM 2Ring
我能读懂C语言,但是我不太理解那段代码。但如果你能理解那段代码的作用,重写它以使用Numpy应该相当简单。虽然速度可能不会像原来那么快,但只要你能用Numpy数组操作编写它,速度应该是可以接受的,因为它们在编译速度下执行。 - PM 2Ring
@PM2Ring,目前执行速度不是我的关注点,而且我也无法完全理解代码的作用。也许我应该在另一个问题中询问这个问题。 - max
“我没有写这段代码,它是做什么用的?”这类问题通常在SO上不太受欢迎。它可能会被关闭为离题。我猜I2M2是宏,可以使用I2(y, x)表示法访问2D IM数组,而不是I[y][x];从旧的weave源代码中可以很容易地检查到这一点。 - PM 2Ring
1个回答

2

Numba可以作为一种替代方案。它可以即时编译Python代码,并且使用非常简洁。

上述代码可以使用装饰器在Python中重新编写:

from numba import jit

@jit
def _thinningIteration(im, iter_):
    M = np.zeros(im.shape, np.uint8)
    h, w = im.shape
    for i in range(1, h - 1):
        for j in range(1, w - 1):
            p2 = im[i - 1, j]
            p3 = im[i - 1, j + 1]
            p4 = im[i, j + 1]
            p5 = im[i + 1, j + 1]
            p6 = im[i + 1, j]
            p7 = im[i + 1, j - 1]
            p8 = im[i, j - 1]
            p9 = im[i - 1, j - 1]
            A = (p2 == 0 and p3 == 1) + (p3 == 0 and p4 == 1) + \
                (p4 == 0 and p5 == 1) + (p5 == 0 and p6 == 1) + \
                (p6 == 0 and p7 == 1) + (p7 == 0 and p8 == 1) + \
                (p8 == 0 and p9 == 1) + (p9 == 0 and p2 == 1)
            B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9
            m1 = (p2 * p4 * p6) if (iter_ == 0) else (p2 * p4 * p8)
            m2 = (p4 * p6 * p8) if (iter_ == 0) else (p2 * p6 * p8)
            if A == 1 and B >= 2 and B <=6 and m1 == 0 and m2 == 0:
                M[i, j] = 1

    return im & ~M

这个程序可以在Python 2.x和Python 3.x中执行,性能接近于C语言。更多细节请查看此链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接