Python 3中无需重写运行含weave的Zhang-Suen细化函数的方法
在Python 3中运行基于weave的Zhang-Suen细化函数
首先得明确:原来的scipy.weave在Python 3里已经被官方弃用并移除了,所以直接跑你贴的原代码肯定行不通。不过不用完全重写核心的细化逻辑,有几个低成本的替代方案,其中改动最小的当属用Numba来替换weave的功能。
方案1:用Numba快速适配(改动最少)
Numba可以通过一个装饰器把Python循环直接编译成机器码,性能和原weave版本差不多,而且几乎不用动核心的判断逻辑。我把你的代码改成了Numba兼容的版本:
import numba import numpy as np @numba.jit(nopython=True) def _thinningIteration(im, iter_num): I = im M = np.zeros(im.shape, np.uint8) NI = im.shape for i in range(1, NI[0]-1): for j in range(1, NI[1]-1): p2 = I[i-1, j] p3 = I[i-1, j+1] p4 = I[i, j+1] p5 = I[i+1, j+1] p6 = I[i+1, j] p7 = I[i+1, j-1] p8 = I[i, j-1] p9 = I[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_num == 0 else p2 * p4 * p8 m2 = p4 * p6 * p8 if iter_num == 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 I & ~M
这里只做了几个很细微的调整:
- 把原weave里的C循环转成了标准的Python循环
- 加了
@numba.jit(nopython=True)装饰器来开启编译加速 - 把参数名
iter改成了iter_num(避免和Python内置的iter()函数重名) - 把C风格的数组索引
I2(i,j)改成了Python/Numpy的I[i,j]格式
这个版本的运行效率和原weave版本几乎没差别,而且完全在Python 3环境里运行,不需要额外的C编译工具链(Numba会自动处理)。
方案2:用Cython封装原逻辑
如果你更倾向于保留原有的C级代码逻辑,也可以用Cython来改写。不过这个方案需要额外的编译步骤,要写.pyx文件和配置编译脚本,相比Numba会麻烦一点,但核心逻辑可以和原C代码几乎一致。
方案3:尝试第三方兼容weave库
曾经有一些第三方库试图把旧的scipy.weave移植到Python 3,比如PyPI上的weave包,但这类库大多维护状态不佳,可能存在各种兼容性问题,不推荐在生产环境使用。
总的来说,Numba是最省心的选择,几乎不用重写核心的细化逻辑,只需要做一点点语法调整,就能让代码在Python 3里高效跑起来。
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

