首页 > 解决方案 > Cython 代码在运行后返回不正确的结果数据类型

问题描述

我正在尝试实现我在 StackOverflow 上找到的一些代码(归功于最有效的计算径向轮廓的方法),并且我发现了一些关于返回变量的问题。正在处理的关键数据类型是一个无符号的 16 位整数;然而,在查看结果时,它们似乎比预期的要高得多。这是我的设置代码,我正在使用 Visual Studio 构建工具进行编译 - 使用 GCC 会更好吗,如果是这样,有人可以指出我关于更改编译器的提示吗?

setup.py代码:

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

ext_options = {"compiler_directives": {"profile": True}, "annotate": True}
setup(
    ext_modules = cythonize("radialAvgCython.pyx", **ext_options),
    include_dirs=[numpy.get_include()]
)

谢谢你的时间!

编辑 3:我想我可能已经发现了问题,它存在于 Cythonic 代码中的一个函数中,如下所示:

cdef void cython_radial_profile(DTYPE_IMG_t [:, :] img_view, DTYPE_t [:] r_profile_view, int xs, int ys, int x0, int y0) nogil:

        cdef int x, y, r, tmp

        for x in prange(xs):
            for y in range(ys):
                r =<int>(sqrt((x - x0)**2 + (y - y0)**2))
                tmp = img_view[x, y]

                r_profile_view[r] +=  tmp 

我相信,对于每个 radius r,该值都被添加到之前的值中,并且没有发生平均;这就是结果往往比预期大得多的原因。我将尝试找到一种方法来平均每个 r,但我认为这可能是核心问题,其结果比其他简单的方位角/径向平均代码大得多。

编辑 2:radialAvgCython.pyx据我所知,这是在 中使用的代码,代码写得很好,但是这与标准径向平均值之间的结果差异很大:

import numpy as np
cimport numpy as np
cimport cython
from cython.parallel import prange
from libc.math cimport sqrt, ceil


DTYPE_IMG = np.uint16
ctypedef np.uint16_t DTYPE_IMG_t
DTYPE = np.int
ctypedef np.int_t DTYPE_t


@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
cdef void cython_radial_profile(DTYPE_IMG_t [:, :] img_view, DTYPE_t [:] r_profile_view, int xs, int ys, int x0, int y0) nogil:

    cdef int x, y, r, tmp

    for x in prange(xs):
        for y in range(ys):
            r =<int>(sqrt((x - x0)**2 + (y - y0)**2))
            tmp = img_view[x, y]

            r_profile_view[r] +=  tmp



@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def radial_profile(np.ndarray img, int centerX, int centerY):

    # Find and define image dimensions.
    cdef int xs, ys, r_max
    xs, ys = img.shape[0], img.shape[1]

    # Find maximum radius based on defined center and image size.
    cdef int topLeft, topRight, botLeft, botRight

    topLeft = <int> ceil(sqrt(centerX**2 + centerY**2))
    topRight = <int> ceil(sqrt((xs - centerX)**2 + (centerY)**2))
    botLeft = <int> ceil(sqrt(centerX**2 + (ys-centerY)**2))
    botRight = <int> ceil(sqrt((xs-centerX)**2 + (ys-centerY)**2))

    r_max = max(topLeft, topRight, botLeft, botRight)

    # Create relevant variables and feed in, solve.
    cdef np.ndarray[DTYPE_t, ndim=1] r_profile = np.zeros([r_max], dtype=DTYPE)
    cdef DTYPE_t [:] r_profile_view = r_profile
    print(r_profile)
    cdef DTYPE_IMG_t [:, :] img_view = img

    with nogil:
        cython_radial_profile(img_view, r_profile_view, xs, ys, centerX, centerY)

    # Return radial profile.
    print(r_profile)
    return r_profile

编辑:我应该提到我正在使用 PyCharm 作为我的 IDE。

标签: pythontypescythoncythonize

解决方案


推荐阅读