使用Cython进行二进制侵蚀加速

时间:2018-04-11 14:43:03

标签: python image-processing scipy cython binary-image

我希望用Cython加速二进制侵蚀图像处理功能,尽管我是Cython的新手。我没有看到我期待的大幅加速。我正在寻找帮助来优化这段代码,因为我仍然不熟悉如何利用C类型,索引,内存视图和对象来提高性能。下面是Cython函数的源代码和输出,使用SciPy模块,setup.py和jupyter notebook的python函数。

Cython代码erode.pyx

import numpy as np
cimport numpy as np

DTYPE = np.int_
ctypedef np.int_t DTYPE_t

def erode(long [:,:] img):

    # Variables
    cdef int height, width, local_min
    cdef int vals[5]
    height = img.shape[0]
    width = img.shape[1]

    # Padded Array
    cdef np.ndarray[DTYPE_t, ndim=2] padded = np.zeros((height+2, width+2), dtype = DTYPE)
    padded[1:height+1,1:width+1] = img

    #Return array
    cdef np.ndarray[DTYPE_t, ndim=2] eroded = np.zeros((height,width),dtype=DTYPE)

    cdef int i,j
    for i in range(height):
        for j in range(width):
            vals = [padded[i+1,j+1], padded[i,j+1], padded[i+1,j],padded[i+1,j+2],padded[i+2,j+1]]
            local_min = min(vals)
            eroded[i,j] = local_min
    return eroded

Python代码erode_py.py

import numpy as np
from scipy.ndimage import binary_erosion


def erode_py(img):

    strel = np.array([[0, 1, 0],
                    [1, 1, 1],
                    [0, 1, 0]], dtype=np.uint8)
    img = img.astype(np.uint8)
    eroded_image = binary_erosion(img, strel, border_value=0)
    return eroded_image

setup.py

from distutils.core import setup
from Cython.Build import cythonize
import numpy


setup(
    name='binary_erode_build',
    ext_modules=cythonize("erode.pyx"),
    include_dirs=[numpy.get_include()]
)

Jupyter笔记本

import numpy as np
import erode
import erode_py

obj = np.array([[0, 0, 0, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 0],
       [0, 0, 0, 1, 1, 1, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 0],
       [0, 1, 1, 1, 1, 1, 0, 0]], dtype=np.int_)

%timeit -n100 -r100 erode.erode(obj)
%timeit -n100 -r100 erode_py.erode_py(obj)

42.8 µs ± 10.3 µs per loop (mean ± std. dev. of 100 runs, 100 loops each)
44.2 µs ± 14.4 µs per loop (mean ± std. dev. of 100 runs, 100 loops each)

0 个答案:

没有答案