scipy 如何更好地利用子区域来提高三维重采样的性能

5f0d552i  于 2023-06-29  发布在  其他
关注(0)|答案(1)|浏览(103)

我有一个形状为(x,y,z)的3D数组,除了沿着z轴的特定索引包含非零值之外,数组中填充了零。我想执行重采样操作以将其大小更改为(x',y',z')。目前,我有一个仿射变换矩阵,我使用scipy.ndimage.affine_transform()函数进行线性插值,阶数=1。然而,性能不是最佳的。
在给定数组的零填充性质和特定索引处存在非零值的情况下,是否有更有效的方法来执行此重采样操作?如何提高重采样过程的性能,同时获得与对所有阵列进行重采样相同的结果?
这是我正在使用的代码的摘要,我相信可以改进

import numpy as np
from scipy.ndimage import affine_transform
import timeit

# Define the original array dimensions
original_shape = (174, 174, 50)

# Define the desired resampled array dimensions
resampled_shape = (112, 112, 70)

# Create the transformation matrix
transform_matrix = np.array([[1.81250001e+00, -3.69390952e-16, -1.34252262e-18, -8.57537821e+00],
                             [3.55472805e-16, 1.77736401e+00, 3.46273023e-01, -2.03978904e+01],
                             [-3.13513815e-17, -1.56756906e-01, 7.64878236e-01, 4.96042520e+00],
                             [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00]])

# Create the original array with zeros
array = np.zeros(original_shape)
# Set the non-zero values at the specific index along the z-axis
z_index = 10 # Is gonna change on each iteration, but I put 10 as an example
array[:, :, z_index] = np.random.randint(2, size=(original_shape[0], original_shape[1]))

# Define a function to perform the resampling
def resample_array():
    return affine_transform(array, transform_matrix, resampled_shape, order=1, mode='constant', cval=0)

# Measure the execution time using timeit
execution_time = timeit.timeit(resample_array, number=1)

# Print the resampled array
print("Resampled array:")
print(resample_array())
# Print the execution time

print("Execution time: {:.2f} seconds".format(execution_time))

使用此代码,在我的计算机上重采样大约需要0.15秒,这对我想要的来说太多了(我们正在做50次)。我已经尝试过对一个切片进行重采样,就像这样

selected_slice = np.zeros([174,174,1])
selected_slice = array[:, :, z_index ] 
sliced_transform = affine_transform(selected_slice, transform_matrix, (112,112,1), order=1, mode='constant', cval=0)
New_array = np.zeros(resampled_shape)
New_array[:, : , z_index] = sliced_transform

但这是显而易见的原因(我们正在做3D重采样),并没有给我与第一种方法相同的结果,所以我不能用这种方法。
那么你们中有没有人有办法在保持相同结果的同时提高时间呢?

r8xiu3jd

r8xiu3jd1#

我使用多处理得到了~ 2.5倍的改进。在100张图像上测试

def resample_array():
    for _ in range(100):
        affine_transform(array, transform_matrix, resampled_shape, order=1, mode='constant', cval=0)

def single_resample(data):
    array, transform_matrix, resampled_shape = data
    affine_transform(array, transform_matrix, resampled_shape, order=1, mode='constant', cval=0)

def resample_array2():

    data_for_multiprocessing = []
    for _ in range(100):
        data_for_multiprocessing.append(
            [array, transform_matrix, resampled_shape]
        )
    with multiprocessing.Pool(8) as pool:
        results = pool.map(single_resample, data_for_multiprocessing)
    return results

if __name__ == '__main__':
    execution_time1 = timeit.timeit(resample_array, number=1)
    execution_time2 = timeit.timeit(resample_array2, number=1)
    print("Execution time: {:.2f} seconds".format(execution_time1))
    print("Execution time multiprocessing: {:.2f} seconds".format(execution_time2))
Execution time: 4.39 seconds
Execution time multiprocessing: 1.62 seconds

相关问题