【发布时间】:2022-12-18 14:49:26
【问题描述】:
我正在用 Cython 编写一个图像处理函数,我需要一个中间数组来存储结果。输入图像具有未知数量的颜色通道(例如 RGB、RGBA 等。我不想为每种输入类型编写单独的函数);这意味着我需要定义一个累加器数组,在其中累加每个颜色通道的中间结果。到目前为止,我有这样的东西,但它不起作用:
# cython: language_level=3
cimport cython
import numpy as np
cimport numpy as np
@cython.wraparound(False)
@cython.boundscheck(False)
cpdef sample_uint8(unsigned char[:, :] img_flat, unsigned short[::1] sizes):
cdef unsigned int x, j, channel, channels, i=0
channels = len(img_flat)
cdef double[channels] accumultors
with nogil:
for x in range(sizes.shape[0]):
# set accumulators to be zero with memset
pass
这会导致编译错误:
Not allowed in a constant expression
我尝试在 for 循环中使用 np.zeros 而不是 memset 但随后出现如下错误:
with nogil:
for x in range(sizes.shape[0]):
cdef double[:] accumulators = np.zeros(channels, dtype='float64')
^
------------------------------------------------------------
C:\Users\OM222O\.ipython\cython\_cython_magic_f87e2bf9fc5c0a8cba87c7930342ff37.pyx:18:17: cdef statement not allowed here
或者使用这个让一切都变得一团糟:
with nogil:
for x in range(sizes.shape[0]):
accumulators = np.zeros(channels, dtype='float64')
不需要 GIL,因为该函数由多个线程使用以获得最佳性能。我尝试弄乱 cimport numpy 和 np.ndarray[type, ndim=2] 等,但没有成功。我知道我可能犯了一个愚蠢的错误,并且有一种简单的方法可以做到这一点,但在查看 Cython 和 Numpy C-API 网站上的可用资源后我找不到它。
我考虑的一个 hack 是创建一个长度为 100 的累加器数组,这意味着该函数最多支持 100 个通道,但是如果数据来自可以有数百甚至数千个通道的神经网络,它就非常对于只有 3 个通道的 RGB 等其他情况效率低下。
请让我知道如何在不增加太多开销和 python 交互的情况下实现这一目标。
附言我用这个将图像转换为扁平通道:
flat = img.reshape(h*w,-1).T
【问题讨论】: