python - 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。
解决方案
推荐阅读
- security - Razor 页面与 Blazor 结合使用是否可以防止过度绑定/过度发布/批量绑定攻击?
- javascript - 在jsp中的警报中有换行符
- java - 在 JNA 中映射原始类型,同时保留本机 typedef 类
- bootstrap-4 - 如何在不破坏原始导航栏布局的情况下添加切换栏?
- powershell - 基于通配符检查组的成员资格(Powershell)
- sql - 雪花 sql 选择查询自动化
- python - 使用Python中的字典从文本文件中提取单词(查找和替换)
- python - 使用dense_vector的Elasticsearch脚本查询余弦相似度给出“class_cast_exception”错误
- css - 为什么“字体大小:calc(1em + 1vw)”在 Safari 上不起作用?(但我的解决方法是)
- cuda - 如果知道warp中所有线程的条件相同,如何避免在CUDA程序中执行条件的两个分支?