Какой диапазон использует Skimage в цветовом пространстве LAB для каждого канала?

При преобразовании изображений из RGB в LAB с помощью skimage.color.rgb2lab я не могу найти документацию, диапазон значений которой может иметь каждый из трех каналов в образе скима. Моя попытка с кодом ниже предлагает, что это будет [0.0, 9341.57] для канала L , [-6952.27, 7924.33] для канала A и [-8700.71, 7621.43] для канала B
Но, на мой взгляд, это не похоже на типичные значения LBA ( [0, 100] , [-170, 100] , [-100, 150] ), которые можно найти в описаниях, и соотношение чисел не выглядит схожим, а также это, как правило, довольно «странные» диапазоны, которые, кажется, вообще не нормализуются.

Итак, какие значения может иметь каждый канал изображения LBA, если он конвертируется skimage ?

(И / или где моя ошибка ниже, попытайтесь определить их?)

# WARN: can take a while to calculate
import numpy as np
from skimage.color import rgb2lab
import multiprocessing as mp

colors = [[r,g,b] for r in range(256) for g in range(256) for b in range(256)]

imgs = np.zeros((16777216,1,1,3))
for i, color in enumerate(colors):
    imgs[i,:,:] = color


labs = np.zeros((16777216,1,1,3))
pool = mp.Pool(mp.cpu_count()-1)
try:
    labs = pool.map(rgb2lab, imgs)
except KeyboardInterrupt:
    # without catching this here we will never be able to manually stop running in a sane way
    pool.terminate()
pool.close()
pool.join()

print(np.min(labs[:,:,:,0]), np.max(labs[:,:,:,0]), np.min(labs[:,:,:,1]), np.max(labs[:,:,:,1]), np.min(labs[:,:,:,2]), np.max(labs[:,:,:,2]))

# 0.0 9341.570221995466 -6952.27373084052 7924.333617630548 -8700.709143439595 7621.42813486568

Всего 1 ответ


Что ж, ваша первая ошибка - использование чистых циклов Python вместо выражений NumPy, но это не по теме. =) Смотрите ниже более эффективную версию того, что вы пытаетесь достичь.

Вторая ошибка является более тонкой и, возможно, самой распространенной ошибкой среди новичков с изображением scikit. Начиная с версии 0.16, scikit-image использует неявные диапазоны данных для различных типов данных, подробно описанных на этой странице . np.zeros умолчанию использует тип данных с плавающей точкой, так что ваш входной массив выше имеет плавающие значения в диапазоне 0-255, что намного больше диапазона, чем ожидаемый 0-1, поэтому вы получите аналогично больший диапазон в пространстве Lab ,

Вы можете увидеть диапазон значений Lab, используя значения numpy.uint8 вместо float, изменив объявление imgs = np.zeros((16777216, 1, 1, 3), dtype=np.uint8) на imgs = np.zeros((16777216, 1, 1, 3), dtype=np.uint8) . Тем не менее, полный код для "NumPy way" ниже:

In [2]: import numpy as np
In [3]: colors = np.mgrid[0:256, 0:256, 0:256].astype(np.uint8)
In [4]: colors.shape
Out[4]: (3, 256, 256, 256)

In [6]: all_rgb = np.transpose(colors)
In [7]: from skimage import color
In [8]: all_lab = color.rgb2lab(all_rgb)
In [9]: np.max(all_lab, axis=(0, 1, 2))
Out[9]: array([100.        ,  98.23305386,  94.47812228])

In [10]: np.min(all_lab, axis=(0, 1, 2))
Out[10]: array([   0.        ,  -86.18302974, -107.85730021])

Чтобы проиллюстрировать проблему диапазона данных, вы можете видеть, что использование ввода с плавающей запятой в 0-1 дает тот же результат:

In [12]: all_lab2 = color.rgb2lab(all_rgb / 255)
In [13]: np.max(all_lab2, axis=(0, 1, 2))
Out[13]: array([100.        ,  98.23305386,  94.47812228])

Есть идеи?

10000