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

При преобразовании изображений из 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 Ответ

3 голосов
/ 17 января 2020

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

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

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

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])
...