我正在试验 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] 删除。
我来说两句