首页 > 解决方案 > np.unravel_index 非常慢

问题描述

假设我有一个分辨率为 H x W x 3 (img) 的图像,并且我有一个该图像的副本,该图像的下采样分辨率为 H' x W' x 3 (resized_img)。现在,假设我想在图像中找到最大值索引,一种方法是

ind=np.unravel_index(np.argmax(img,axis=None),img.shape)

但如果分辨率较大,则此方法速度较慢。另一方面,我可以在调整大小的 img 上找到最大索引

img_resized=np.unravel(np.argmax(resized_img,axis=None),resized_img.shape)

现在,如果我想要原始图像中的相应索引,我只是乘以比例因子还是如何做到这一点?

如果 H=W 和 H'=W' 那么我可以相信我需要做的就是让

scale_factor=H/H'=W/W'

ind=resized_ind * scale_factor

但我不确定这是否正确以及如何处理 $H \neq W$ 时的情况。

标签: pythonalgorithmnumpy

解决方案


``ravel/unravel 不改变数组;他们只是根据形状计算新的指数。

考虑一个简单的 3d 数组:

In [63]: arr = np.arange(24).reshape(2,3,4)
In [64]: arr
Out[64]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

该数组中具有索引元组的点:

In [65]: arr[0,1,2]
Out[65]: 6

解开和解开:

In [66]: np.ravel_multi_index([0,1,2],arr.shape)
Out[66]: 6
In [67]: np.unravel_index(6, arr.shape)
Out[67]: (0, 1, 2)

有一种ravel方法,但这只是 a reshape,因此是 a view(至少在order等方面没有变化):

In [69]: arr.ravel()
Out[69]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])

计算ravel_multi_index只是:

In [70]: 2 + 4*1 + 12*0
Out[70]: 6

而是unravel某种相反的。我不会详细介绍,但它可能使用某种模数。


解决此问题的另一种方法是比较两种不同形状的运行时间:

In [71]: np.unravel_index(1000, (1080,1620,3))
Out[71]: (0, 333, 1)
In [72]: np.unravel_index(1000, (256,256,3))
Out[72]: (1, 77, 1)
In [73]: timeit np.unravel_index(1000, (1080,1620,3))
5.14 µs ± 128 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [74]: timeit np.unravel_index(1000, (256,256,3))
4.84 µs ± 29.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

两种形状的运行时间大致相同(它们在 ± 因子内重叠。)


推荐阅读