9. 图像调整:转换图像内容#

9.1. 颜色操作#

大多数用于操作颜色通道的函数都可以在子模块 skimage.color 中找到。

9.1.1. 颜色模型之间的转换#

彩色图像可以使用不同的 色彩空间 来表示。最常见的色彩空间之一是 RGB空间,其中图像具有红色、绿色和蓝色通道。然而,其他色彩模型也被广泛使用,例如 HSV色彩模型,其中色调、饱和度和亮度是独立的通道,或者是用于印刷的 CMYK模型

skimage.color 提供了将图像在不同颜色空间之间转换的实用函数。整数类型的数组可以通过转换操作转换为浮点类型:

>>> # bright saturated red
>>> red_pixel_rgb = np.array([[[255, 0, 0]]], dtype=np.uint8)
>>> color.rgb2hsv(red_pixel_rgb)
array([[[ 0.,  1.,  1.]]])
>>> # darker saturated blue
>>> dark_blue_pixel_rgb = np.array([[[0, 0, 100]]], dtype=np.uint8)
>>> color.rgb2hsv(dark_blue_pixel_rgb)
array([[[ 0.66666667,  1.        ,  0.39215686]]])
>>> # less saturated pink
>>> pink_pixel_rgb = np.array([[[255, 100, 255]]], dtype=np.uint8)
>>> color.rgb2hsv(pink_pixel_rgb)
array([[[ 0.83333333,  0.60784314,  1.        ]]])

9.1.2. 从 RGBA 转换为 RGB - 通过 alpha 混合去除 alpha 通道#

通过将RGBA图像与背景进行alpha混合来转换为RGB图像,可以通过 rgba2rgb() 实现:

>>> import skimage as ski
>>> img_rgba = ski.data.logo()
>>> img_rgb = ski.color.rgba2rgb(img_rgba)

9.1.3. 颜色和灰度值之间的转换#

将RGB图像转换为灰度图像是通过 rgb2gray() 实现的

>>> img = ski.data.astronaut()
>>> img_gray = ski.color.rgb2gray(img)

rgb2gray() 使用颜色通道的非均匀加权,这是因为人眼对不同颜色的敏感度不同。因此,这种加权确保了从RGB到灰度的 亮度保留:

>>> red_pixel = np.array([[[255, 0, 0]]], dtype=np.uint8)
>>> ski.color.rgb2gray(red_pixel)
array([[ 0.2125]])
>>> green_pixel = np.array([[[0, 255, 0]]], dtype=np.uint8)
>>> ski.color.rgb2gray(green_pixel)
array([[ 0.7154]])

使用 gray2rgb() 将灰度图像转换为RGB图像,只需将灰度值在三个颜色通道上进行复制。

9.1.4. 图像反转#

倒置图像也称为互补图像。对于二值图像,True 值变为 False,反之亦然。对于灰度图像,像素值被数据类型的最大值与实际值之差替换。对于 RGB 图像,每个通道都进行相同的操作。此操作可以通过 skimage.util.invert() 实现:

>>> import skimage as ski
>>> img = ski.data.camera()
>>> inverted_img = ski.util.invert(img)

9.1.5. 用标签绘制图像#

label2rgb() 可以用于使用标签数组将颜色叠加在灰度图像上,以编码要用相同颜色表示的区域。

../_images/sphx_glr_plot_join_segmentations_001.png

9.2. 对比度和曝光#

图像像素可以取由图像的 dtype 决定的值(参见 数据类型),例如 uint8 图像的 0 到 255 或浮点图像的 [0, 1]。然而,大多数图像要么由于对比度差而具有较窄的值范围,要么大多数像素值集中在可访问值的子范围内。skimage.exposure 提供了扩展强度值范围的函数。

第一类方法计算强度的非线性函数,该函数与特定图像的像素值无关。这类方法常用于校正传感器或接收器(如人眼)的已知非线性。一个著名的例子是 Gamma 校正,在 adjust_gamma() 中实现。

其他方法根据图像的 直方图 重新分配像素值。像素值的直方图通过 skimage.exposure.histogram() 计算:

>>> import numpy as np
>>> import skimage as ski
>>> image = np.array([[1, 3], [1, 1]])
>>> ski.exposure.histogram(image)
(array([3, 0, 1]), array([1, 2, 3]))

histogram() 返回每个值区间的像素数量以及区间的中点。因此,histogram() 的行为与 numpy.histogram() 略有不同,后者返回区间的边界。

最简单的对比度增强 rescale_intensity() 包括将像素值拉伸到整个允许的范围,使用线性变换:

>>> import skimage as ski
>>> text = ski.data.text()
>>> text.min(), text.max()
(10, 197)
>>> better_contrast = ski.exposure.rescale_intensity(text)
>>> better_contrast.min(), better_contrast.max()
(0, 255)

即使图像使用了整个值范围,有时在值范围的两端几乎没有权重。在这种情况下,使用图像的百分位数裁剪像素值可以提高对比度(以牺牲一些信息为代价,因为某些像素在此操作中被饱和):

>>> moon = ski.data.moon()
>>> v_min, v_max = np.percentile(moon, (0.2, 99.8))
>>> v_min, v_max
(10.0, 186.0)
>>> better_contrast = ski.exposure.rescale_intensity(moon, in_range=(v_min, v_max))

函数 equalize_hist() 将像素值的累积分布函数(cdf)映射到线性 cdf 上,确保值范围内的所有部分在图像中都得到同等表示。因此,细节在对比度较差的大区域中得到增强。进一步的改进是,可以使用 equalize_adapthist() 在图像的子区域中进行直方图均衡化,以校正图像中曝光梯度。请参见示例 直方图均衡化

../_images/sphx_glr_plot_equalize_001.png