前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >计算机视觉101:使用Python处理彩色图像

计算机视觉101:使用Python处理彩色图像

作者头像
代码医生工作室
发布2020-03-27 13:40:02
2K0
发布2020-03-27 13:40:02
举报
文章被收录于专栏:相约机器人相约机器人

作者 | Eryk Lewinson

来源 | Medium

编辑 | 代码医生团队

每个计算机视觉项目(无论是猫/狗分类器还是为旧图像/电影添加颜色)都涉及处理图像。最后,模型只能与基础数据一样好- 垃圾回收。这就是为什么在这篇文章中,着重于解释在Python中使用彩色图像的基本知识,它们的表示方式以及如何将图像从一种颜色表示转换为另一种颜色表示。

设定

在本节中,设置Python环境。首先导入所有必需的库:

代码语言:javascript
复制
import numpy as npfrom skimage.color import rgb2lab, rgb2gray, lab2rgbfrom skimage.io import imread, imshowimport matplotlib.pyplot as plt

使用scikit-image,它是scikit-learn的家族库,专注于处理图像。还有许多其他的方法,一些库包括matplotlib,numpy,OpenCV等。

在第二步中,定义了一个辅助函数,用于打印有关图像信息的摘要-图像的形状以及每个图层中值的范围。

代码语言:javascript
复制
def print_image_summary(image, labels):
    print('--------------')    print('Image Details:')    print('--------------')    print(f'Image dimensions: {image.shape}')    print('Channels:')
    if len(labels) == 1:        image = image[..., np.newaxis]
    for i, lab in enumerate(labels):        min_val = np.min(image[:,:,i])        max_val = np.max(image[:,:,i])        print(f'{lab} : min={min_val:.4f}, max={max_val:.4f}')

函数的逻辑非常简单,一旦描述了图像的存储方式,就可以对尺寸进行切片。

灰阶

从最基本的情况开始,即灰度图像。此类图像仅由灰色阴影制成。极端是黑色(最弱强度的对比度)和白色(强度最强)。

在引擎盖下,图像存储为整数矩阵,其中像素的值对应于给定的灰色阴影。灰度图像的值的范围从0(黑色)到255(白色)。下图提供了对该概念的直观概述。

在本文中,将使用您已经看到的缩略图(彩色蜡笔圈)的图像进行处理。选择如此彩色的图片并非偶然:)

首先将灰度图像加载到Python中并进行打印。

代码语言:javascript
复制
image_gs = imread('crayons.jpg', as_gray=True)fig, ax = plt.subplots(figsize=(9, 16))imshow(image_gs, ax=ax)ax.set_title('Grayscale image')ax.axis('off');

由于原始图像是彩色的,因此通常as_gray=True将其加载为灰度图像。另外,可以使用默认设置加载图像imread(加载RGB图像-在下一节中介绍),然后使用rgb2gray函数将其转换为灰度。

接下来,运行助手功能以打印图像摘要。

代码语言:javascript
复制
print_image_summary(image_gs, ['G'])

运行代码将产生以下输出:

代码语言:javascript
复制
--------------Image Details:--------------Image dimensions: (1280, 1920)Channels:G : min=0.0123, max=1.0000

图像存储为1280行x 1920列的2D矩阵(高清分辨率)。通过查看最小值和最大值,可以看到它们在[0,1]范围内。这是因为它们会自动除以255,这是处理图像的常见预处理步骤。

RGB

现在是时候使用颜色了。从RGB模型开始。简而言之,它是一种加法模型,其中将红色,绿色和蓝色(因此得名)的阴影以各种比例添加到一起,以再现各种颜色。

在中scikit-image,这是使用以下命令加载图像的默认模型imread:

代码语言:javascript
复制
image_rgb = imread('crayons.jpg')

在打印图像之前,检查摘要以了解图像在Python中的存储方式。

代码语言:javascript
复制
print_image_summary(image_rgb, ['R', 'G', 'B'])

运行代码将生成以下摘要:

代码语言:javascript
复制
--------------Image Details:--------------Image dimensions: (1280, 1920, 3)Channels:R : min=0.0000, max=255.0000G : min=0.0000, max=255.0000B : min=0.0000, max=255.0000

与灰度图像相比,这次将图像存储为3D np.ndarray。附加尺寸代表3个颜色通道中的每一个。和以前一样,颜色的强度以0-255的比例表示。它经常重新调整为[0,1]范围。然后,任何一层中的像素值为0表示该像素在该特定通道中没有颜色。

一个有用的注意事项:使用OpenCV的imread功能时,图像将以BGR(而不是RGB)加载。为了使其与其他库兼容,需要更改通道的顺序。

现在该打印图像和不同的颜色通道了:

代码语言:javascript
复制
fig, ax = plt.subplots(1, 4, figsize = (18, 30))ax[0].imshow(image_rgb/255.0)ax[0].axis('off')ax[0].set_title('original RGB')for i, lab in enumerate(['R','G','B'], 1):    temp = np.zeros(image_rgb.shape)    temp[:,:,i - 1] = image_rgb[:,:,i - 1]    ax[i].imshow(temp/255.0)    ax[i].axis("off")    ax[i].set_title(lab)plt.show()

在下面的图像中,可以分别看到原始图像和3个颜色通道。喜欢这张图像的是,通过关注各个蜡笔,可以看到RGB通道中的哪些颜色以及哪些比例构成了原始图像中的最终颜色。

另外,可以绘制单独的颜色通道,如下所示:

代码语言:javascript
复制
fig, ax = plt.subplots(1, 4, figsize = (18, 30))ax[0].imshow(image_rgb)ax[0].axis('off')ax[0].set_title('original RGB')for i, cmap in enumerate(['Reds','Greens','Blues']):    ax[i+1].imshow(image_rgb[:,:,i], cmap=cmap)    ax[i+1].axis('off')    ax[i+1].set_title(cmap[0])plt.show()

什么生成以下输出:

对于这种绘制RGB通道的方式,更喜欢的是发现更容易区分不同的颜色(由于其他颜色更浅,更透明,所以它们更加突出)及其强度。

在进行图像分类任务时,经常会遇到RGB图像。在为该任务应用卷积神经网络(CNN)时,需要将所有操作应用于所有3个颜色通道。在本文中,展示了如何使用CNN处理二进制图像分类问题。

Lab

除了RGB外,另一种流行的表示彩色图像的方法是使用Lab色彩空间(也称为CIELAB)。

在详细介绍之前,有必要指出颜色模型和颜色空间之间的区别。颜色模型是描述颜色的数学方法。颜色空间是将真实的,可观察的颜色映射到颜色模型的离散值的方法。有关更多详细信息,请参阅此答案。

Lab颜色空间将颜色表示为三个值:

  • L:亮度从0(黑色)到100(白色)的比例,实际上是灰度图像
  • a:绿红色色谱,值范围从-128(绿色)到127(红色)
  • b:蓝黄色色谱,值范围从-128(蓝色)到127(黄色)

换句话说,Lab将图像编码为灰度层,并将三个颜色层缩减为两个。

首先将图像从RGB转换为Lab并打印图像摘要:

代码语言:javascript
复制
image_lab = rgb2lab(image_rgb / 255)

该rgb2lab函数假定RGB标准化为0到1之间的值,这就是为什么将所有值除以255的原因。从下面的摘要中,看到Lab值的范围落在上面指定的范围内。

代码语言:javascript
复制
--------------Image Details:--------------Image dimensions: (1280, 1920, 3)Channels:L : min=0.8618, max=100.0000a : min=-73.6517, max=82.9795b : min=-94.7288, max=91.2710

下一步,将图像可视化-实验一个和每个通道分开。

代码语言:javascript
复制
fig, ax = plt.subplots(1, 4, figsize = (18, 30))ax[0].imshow(image_lab)ax[0].axis('off')ax[0].set_title('Lab')for i, col in enumerate(['L', 'a', 'b'], 1):    imshow(image_lab[:, :, i-1], ax=ax[i])    ax[i].axis('off')    ax[i].set_title(col)fig.show()

第一次尝试绘制实验室图像

好吧,第一次可视化Lab颜色空间的尝试远没有成功。第一张图片几乎无法识别,L层不是灰度。根据此答案的见解,为了正确打印,必须将Lab值重新缩放到[0,1]范围。这次,第一层的缩放比例与后两层的缩放比例不同。

代码语言:javascript
复制
#scale the lab imageimage_lab_scaled = (image_lab + [0, 128, 128]) / [100, 255, 255]fig, ax = plt.subplots(1, 4, figsize = (18, 30))ax[0].imshow(image_lab_scaled)ax[0].axis('off')ax[0].set_title('Lab scaled')for i, col in enumerate(['L', 'a', 'b'], 1):    imshow(image_lab_scaled[:, :, i-1], ax=ax[i])    ax[i].axis('off')    ax[i].set_title(col)
fig.show()

第二次尝试要好得多。在第一个图像中,看到了彩色图像的Lab表示。这次,L层是实际的灰度图像。仍然可以改进的是最后两层,因为它们也是灰度的。

第二次尝试绘制实验室图像

在最后一次尝试中,将颜色映射应用于Lab图像的a和b层。

代码语言:javascript
复制
fig, ax = plt.subplots(1, 4, figsize = (18, 30))ax[0].imshow(image_lab_scaled)ax[0].axis('off')ax[0].set_title('Lab scaled')imshow(image_lab_scaled[:,:,0], ax=ax[1])ax[1].axis('off')ax[1].set_title('L')ax[2].imshow(image_lab_scaled[:,:,1], cmap='RdYlGn_r')ax[2].axis('off')ax[2].set_title('a')ax[3].imshow(image_lab_scaled[:,:,2], cmap='YlGnBu_r')ax[3].axis('off')ax[3].set_title('b')
plt.show()

这次结果令人满意。可以清楚地区分a和b层中的不同颜色。颜色图本身仍然可以改进。为了简单起见,使用的预定义的颜色映射,其含有在其之间的两个极端的人(黄色层的滤色一个,绿色在b层)。潜在的解决方案是手动编码颜色图。

第三次尝试绘制实验室图像

处理图像着色问题(例如著名的DeOldify)时,通常会遇到实验室图像。

https://github.com/jantic/DeOldify

结论

在本文中,介绍了在Python中使用彩色图像的基础知识。使用提出的技术,可以自己开始解决计算机视觉问题。认为了解图像的存储方式以及如何将其转换为不同的表示形式非常重要,这样在训练深度神经网络时就不会遇到意料之外的问题。

另一个流行的色彩空间是XYZ。scikit-image还包含将RGB或Lab图像转换为XYZ的功能。

可以在GitHub上找到用于本文的代码。

https://github.com/erykml/medium_articles/blob/master/Computer%20Vision/working_with_color_images.ipynb

参考文献

https://ai.stanford.edu/~syyeung/cvweb/tutorial1.html

https://github.com/scikit-image/scikit-image/issues/1185

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档