使用 OpenCV 时 Cython 比 Python 慢

莱兹旺·卡斯特利诺

我正在试验 Cython 和 OpenCV,并尝试对图像处理的性能进行基准测试。我已经尝试尽可能多地优化我的 Cython 代码,但我的性能仍然很慢。我知道由于 OpenCV,大部分代码都是在 C 中执行的,但我希望使用 Cython 的 python 循环有更好的性能。谁能告诉我我是否可以做些什么来改进它?以下是我的代码:

# load_images.py

import cv2
from random import randint
import numpy as np

def fetch_images(n):
    def get_img():
        x = randint(640, 6144)
        y = randint(640, 6144)
        return np.random.rand(x,y, 3).astype(np.uint8)

    return [get_img() for _ in range(n)]

def resize_img(img):
    img = cv2.resize(img, (640, 640))
    return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


def preprocess(images):
    return [resize_img(img) for img in images]
# load_images_cy.pyx

import cv2
from random import randint
import numpy as np
cimport numpy as np
cimport cython
ctypedef np.uint8_t DTYPE_t

@cython.boundscheck(False)
@cython.wraparound(False)

cdef np.ndarray[DTYPE_t, ndim=3] get_img():
    cdef int x = randint(640, 6144)
    cdef int y = randint(640, 6144)
    return np.random.rand(x,y, 3).astype(np.uint8)

cpdef list fetch_images(int n):
    cdef int _;
    return [get_img() for _ in range(n)]

cdef np.ndarray[DTYPE_t, ndim=2] resize_img(np.ndarray[DTYPE_t, ndim=3] img):
    cdef np.ndarray[DTYPE_t, ndim=3] im;
    im = cv2.resize(img, (640, 640))
    return cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)


cpdef np.ndarray[DTYPE_t, ndim=3] preprocess(list images):
    cdef np.ndarray[DTYPE_t, ndim=3] img;
    cdef np.ndarray[DTYPE_t, ndim=3] collection = np.empty((len(images), 640, 640), dtype=np.uint8);
    cdef int i;

    for i, img in enumerate(images):
        collection[i] = resize_img(img)

    return collection
# main.py

import load_images_cy
import load_images

import timeit

images = load_images.fetch_images(20)

result_cy = timeit.timeit(lambda: load_images_cy.preprocess(images), number=20)
result_py = timeit.timeit(lambda: load_images.preprocess(images), number=20)
print(f'{result_py/result_cy} times faster')

输出:

0.9192241989059127 times faster
威尔·达席尔瓦

Cython 主要用于与 C 代码交互,并更轻松地编写Python 扩展模块虽然可以通过 Cython 获得性能改进,但它并不打算成为 Python 代码的直接加速。

然而,PyPy旨在或多或少地加速 Python 代码。它提供了一个替代解释器,它通常比 CPython(参考/默认 Python 实现)更快。

此外,您的装饰者在这里:

@cython.boundscheck(False)
@cython.wraparound(False)

cdef np.ndarray[DTYPE_t, ndim=3] get_img():
    ...

仅适用于get_img-不适用于以下任何其他功能。不确定这是故意的还是无意的。这些之间不应有空行。

如果您想坚持使用 Cython 并通过它获得性能改进,请考虑更改编译选项,例如提供-O2-O3

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章