Numpy Image Arrays: как эффективно переключаться с RGB на Hex
Я использовал вложенные циклы for, чтобы превратить изображения RGB в массив изображений с шестнадцатеричными значениями, но это слишком медленно для больших изображений. Кто-нибудь знает быстрый способ и / или библиотеку, которая может помочь мне переключиться назад и с RGB на HEX?
редактировать: @ragingSloth
Это то, что я придумал, но это слишком медленно для того, что мне нужно:
def rgb_to_hex(array):
(x, y, z) = array.shape
for v in range(0, x):
for u in range(0, y):
array[v, u] = int('%02x%02x%02x' % (array[v, u, 0], array[v, u, 1], array[v, u, 2]))
3 ответа
Используя идею мензурки, вы также можете исключить двойной цикл for:
def tohex(array):
array = np.asarray(array, dtype='uint32')
return ((array[:, :, 0]<<16) + (array[:, :, 1]<<8) + array[:, :, 2])
Строковые операции, вероятно, довольно медленные. Прямой математический подход будет:
array[v, u] = ((array[v, u, 0]<<16) + (array[v, u, 1]<<8) + array[v, u, 2])
Это объединяет 3 байта RGB-представления в одно целое:
>>> A = [123, 255, 255]
>>> B = (A[0]<<16) + (A[1]<<8) + A[2]
>>> B
8126463
>>> hex(B)
'0x7bffff'
Не уверен, что это намного быстрее, но вы могли бы сделать что-то вроде этого:
hexarr = np.vectorize('{:02x}'.format)
А затем запустите его на массиве RGB:
In [67]: a = (np.random.rand(2,5,3)*255).astype('u1')
In [68]: a
Out[68]:
array([[[149, 145, 203],
[210, 234, 219],
[223, 50, 26],
[166, 34, 65],
[213, 78, 115]],
[[191, 54, 168],
[ 85, 235, 36],
[180, 140, 96],
[127, 21, 24],
[166, 210, 128]]], dtype=uint8)
In [69]: hexarr(a)
Out[69]:
array([[['95', '91', 'cb'],
['d2', 'ea', 'db'],
['df', '32', '1a'],
['a6', '22', '41'],
['d5', '4e', '73']],
[['bf', '36', 'a8'],
['55', 'eb', '24'],
['b4', '8c', '60'],
['7f', '15', '18'],
['a6', 'd2', '80']]],
dtype='|S2')
Вы можете свернуть третье измерение с view
:
In [71]: hexarr(a).view('S6')
Out[71]:
array([[['9591cb'],
['d2eadb'],
['df321a'],
['a62241'],
['d54e73']],
[['bf36a8'],
['55eb24'],
['b48c60'],
['7f1518'],
['a6d280']]],
dtype='|S6')
К сожалению, это не кажется намного быстрее (чуть более чем в два раза быстрее):
In [89]: timeit rgb_to_hex(a)
1 loops, best of 3: 6.83 s per loop
In [90]: timeit hexarr(a).view('S6')
1 loops, best of 3: 2.54 s per loop