skimage 在每个通道的 LAB 颜色 space 中使用什么范围?
What range does skimage use in LAB color space for each channel?
当使用 skimage.color.rgb2lab
将图像从 RGB 转换为 LAB 时,我真的找不到文档,三个通道中的每个通道在 skimage 中可以具有哪个值范围。
我尝试使用下面的代码建议 L
通道为 [0.0, 9341.57]
,A
通道为 [-6952.27, 7924.33]
,B
通道为 [-8700.71, 7621.43]
。
但在我看来,这既不像描述中可以找到的典型 LBA 值([0, 100]
、[-170, 100]
、[-100, 150]
),数字的比率也不像看起来很相似,而且这些范围通常 'odd' 看起来似乎根本没有标准化。
那么LBA图像的每个通道如果经过skimage
转换可以有多少值呢?
(And/or 我在下面尝试确定它们的错误在哪里?)
# 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
好吧,您的第一个错误是使用纯 Python 循环而不是 NumPy 表达式,但这是题外话。 =) 请参阅下文,了解您要实现的目标的更有效版本。
第二个错误更微妙,可能是 scikit-image 新手最常犯的错误。从 0.16 版本开始,scikit-image 对不同的数据类型使用隐式数据范围,详见 this page。 np.zeros
默认为 float 数据类型,因此上面的输入数组的浮点数范围为 0-255,这比预期的 0-1 范围大得多,因此您最终得到的范围类似实验室 space.
通过将 imgs
声明更改为 imgs = np.zeros((16777216, 1, 1, 3), dtype=np.uint8)
,您可以使用 numpy.uint8
值而不是浮点数来查看 Lab 值的范围。但是,"the 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])
当使用 skimage.color.rgb2lab
将图像从 RGB 转换为 LAB 时,我真的找不到文档,三个通道中的每个通道在 skimage 中可以具有哪个值范围。
我尝试使用下面的代码建议 L
通道为 [0.0, 9341.57]
,A
通道为 [-6952.27, 7924.33]
,B
通道为 [-8700.71, 7621.43]
。
但在我看来,这既不像描述中可以找到的典型 LBA 值([0, 100]
、[-170, 100]
、[-100, 150]
),数字的比率也不像看起来很相似,而且这些范围通常 'odd' 看起来似乎根本没有标准化。
那么LBA图像的每个通道如果经过skimage
转换可以有多少值呢?
(And/or 我在下面尝试确定它们的错误在哪里?)
# 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
好吧,您的第一个错误是使用纯 Python 循环而不是 NumPy 表达式,但这是题外话。 =) 请参阅下文,了解您要实现的目标的更有效版本。
第二个错误更微妙,可能是 scikit-image 新手最常犯的错误。从 0.16 版本开始,scikit-image 对不同的数据类型使用隐式数据范围,详见 this page。 np.zeros
默认为 float 数据类型,因此上面的输入数组的浮点数范围为 0-255,这比预期的 0-1 范围大得多,因此您最终得到的范围类似实验室 space.
通过将 imgs
声明更改为 imgs = np.zeros((16777216, 1, 1, 3), dtype=np.uint8)
,您可以使用 numpy.uint8
值而不是浮点数来查看 Lab 值的范围。但是,"the 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])