在我生成的数组中,我有一个图像读入numpy中有很多像素。
我计算了一个包含256个值的查找表。现在我想做以下事情:
for i in image.rows:
for j in image.cols:
mapped_image[i,j] = lut[image[i,j]]
是的,这基本上就像一个人 唯一的问题是:我想做得高效并在python中调用该循环将让我等待几秒钟才能完成。
我知道numpy.vectorize()
,它只是一个调用相同python代码的便捷函数。
答案 0 :(得分:35)
如果image
1D ,您可以使用lut
为lut
编入索引。
这是NumPy索引的首发:
http://www.scipy.org/Tentative_NumPy_Tutorial#head-864862d3f2bb4c32f04260fac61eb4ef34788c4c
In [54]: lut = np.arange(10) * 10
In [55]: img = np.random.randint(0,9,size=(3,3))
In [56]: lut
Out[56]: array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
In [57]: img
Out[57]:
array([[2, 2, 4],
[1, 3, 0],
[4, 3, 1]])
In [58]: lut[img]
Out[58]:
array([[20, 20, 40],
[10, 30, 0],
[40, 30, 10]])
还要注意索引从0
答案 1 :(得分:16)
np.take
,根据文档“执行与花哨索引相同的操作。”
嗯,差不多,但不完全一样:
>>> import numpy as np
>>> lut = np.arange(256)
>>> image = np.random.randint(256, size=(5000, 5000))
>>> np.all(lut[image] == np.take(lut, image))
True
>>> import timeit
>>> timeit.timeit('lut[image]',
... 'from __main__ import lut, image', number=10)
4.369504285407089
>>> timeit.timeit('np.take(lut, image)',
... 'from __main__ import np, lut, image', number=10)
1.3678052776554637
np.take
大约快3倍!根据我的经验,当使用3D luts将图像从RGB转换为其他色彩空间时,添加逻辑以将3D查找转换为1D平坦查找可以使x10加速。
答案 2 :(得分:0)
如果您仅限使用numpy,则可以使用TheodrosZelleke's answer。但是,如果允许其他模块,则cv2
是用于与图像数据进行交互的有用模块,它接受numpy数组作为输入。一个很大的限制是图像数组必须具有dtype='uint8'
,但是只要可以,函数cv2.LUT
就可以实现我们想要的功能,并且可以大大提高速度:
>>> import numpy as np
>>> import cv2
>>> lut = np.arange(256, dtype='uint8')
>>> image = np.random.randint(256, size=(5000, 5000), dtype='uint8')
>>> np.all(lut[image] == cv2.LUT(image, lut))
True
>>> import timeit
>>> timeit.timeit('lut[image]', 'from __main__ import lut, image', number=10)
0.5747578000000431
>>> timeit.timeit('cv2.LUT(image, lut)',
... 'from __main__ import cv2, lut, image', number=10)
0.07559149999997317
您的查询表可以是其他数据类型,但是您在速度上有很多改进(尽管numpy索引也会影响性能)。例如,使用dtype='float64'
:
>>> lut = np.arange(256, dtype='float64')
>>> timeit.timeit('lut[image]', 'from __main__ import lut, image', number=10)
1.068468699999812
>>> timeit.timeit('cv2.LUT(image, lut)',
... 'from __main__ import cv2, lut, image', number=10)
0.41085720000000947