gpt4 book ai didi

Python 3D插值加速

转载 作者:太空宇宙 更新时间:2023-11-03 11:21:54 24 4
gpt4 key购买 nike

我有以下用于插入 3D 体积数据的代码。

Y, X, Z = np.shape(volume)
xs = np.arange(0, X)
ys = np.arange(0, Y)
zs = np.arange(0, Z)

points = list(zip(np.ravel(result[:, :, :, 1]), np.ravel(result[:, :, :, 0]), np.ravel(result[:, :, :, 2])))
interp = interpolate.RegularGridInterpolator((ys, xs, zs), volume,
bounds_error=False, fill_value=0, method='linear')
new_volume = interp(points)
new_volume = np.reshape(new_volume, (Y, X, Z))

此代码在 512x512x110 体积(约 2900 万个点)上执行大约需要 37 秒,这导致每个体素超过 1 微秒(这对我来说是 Not Acceptable 时间——更重要的是它使用 4 个内核)。调用 new_volume=interp(points) 占用了大约 80% 的程序时间,列表创建几乎占用了全部剩余时间。

是否有任何简单(或什至更复杂)的方法可以加快计算速度?或者是否有任何好的 Python 库可以提供更快的插值?每次调用此程序时,我的音量和积分都会发生变化。

最佳答案

这是您的 cython 解决方案的略微修改版本:

import numpy as np
cimport numpy as np
from libc.math cimport floor
from cython cimport boundscheck, wraparound, nonecheck, cdivision

DTYPE = np.float
ctypedef np.float_t DTYPE_t

@boundscheck(False)
@wraparound(False)
@nonecheck(False)
def interp3D(DTYPE_t[:,:,::1] v, DTYPE_t[:,:,::1] xs, DTYPE_t[:,:,::1] ys, DTYPE_t[:,:,::1] zs):

cdef int X, Y, Z
X,Y,Z = v.shape[0], v.shape[1], v.shape[2]
cdef np.ndarray[DTYPE_t, ndim=3] interpolated = np.zeros((X, Y, Z), dtype=DTYPE)

_interp3D(&v[0,0,0], &xs[0,0,0], &ys[0,0,0], &zs[0,0,0], &interpolated[0,0,0], X, Y, Z)
return interpolated


@cdivision(True)
cdef inline void _interp3D(DTYPE_t *v, DTYPE_t *x_points, DTYPE_t *y_points, DTYPE_t *z_points,
DTYPE_t *result, int X, int Y, int Z):

cdef:
int i, x0, x1, y0, y1, z0, z1, dim
DTYPE_t x, y, z, xd, yd, zd, c00, c01, c10, c11, c0, c1, c

dim = X*Y*Z

for i in range(dim):
x = x_points[i]
y = y_points[i]
z = z_points[i]

x0 = <int>floor(x)
x1 = x0 + 1
y0 = <int>floor(y)
y1 = y0 + 1
z0 = <int>floor(z)
z1 = z0 + 1

xd = (x-x0)/(x1-x0)
yd = (y-y0)/(y1-y0)
zd = (z-z0)/(z1-z0)

if x0 >= 0 and y0 >= 0 and z0 >= 0:
c00 = v[Y*Z*x0+Z*y0+z0]*(1-xd) + v[Y*Z*x1+Z*y0+z0]*xd
c01 = v[Y*Z*x0+Z*y0+z1]*(1-xd) + v[Y*Z*x1+Z*y0+z1]*xd
c10 = v[Y*Z*x0+Z*y1+z0]*(1-xd) + v[Y*Z*x1+Z*y1+z0]*xd
c11 = v[Y*Z*x0+Z*y1+z1]*(1-xd) + v[Y*Z*x1+Z*y1+z1]*xd

c0 = c00*(1-yd) + c10*yd
c1 = c01*(1-yd) + c11*yd

c = c0*(1-zd) + c1*zd

else:
c = 0

result[i] = c

结果仍然与您的相同。使用 60x60x60 的随机网格数据,我获得以下时间:

SciPy's solution:                982ms
Your cython solution: 24.7ms
Above modified cython solution: 8.17ms

所以它比您的 cython 解决方案快将近 4 倍。注意

  1. Cython 默认对数组执行边界检查,如果您需要该功能,请打开边界检查并删除 @boundscheck(False)
  2. 在上面的解决方案中,数组需要是 C 连续的
  3. 如果您想要上述代码的并行变体,请在您的for 循环 中替换range 而不是prange

希望这对您有所帮助。

关于Python 3D插值加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41220617/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com