如果您一直在使用 Python 进行编程,那么您很可能至少遇到过一个提供处理颜色表示和自定义功能的库。
From 图像处理从数据可视化到Web应用程序开发,你会发现颜色的使用无处不在。
事实上,大多数用于最先进计算机视觉任务的现代深度神经网络都是根据图像中像素颜色信息的空间分布进行训练的。
在本教程中,我们将了解其中一些库,并了解如何以编程方式描述和修改颜色。
计算机中的颜色表示
在查看特定的 Python 库之前,让我们首先了解颜色在计算机程序中通常是如何表示的。
有许多流行的颜色模型用于描述颜色,例如 RGB、CMYK、HSV、HSL 等。
RGB 颜色模型最常用于编程语言中。
RGB颜色模型
在RGB颜色模型中,任何颜色都可以通过混合3种原色(即红、绿、蓝)来生成。
在此模型中,可以通过指定一组 3 个数值(通常范围从 0 到 255)来描述颜色,
每个指定给定颜色中存在的红色、绿色和蓝色的强度。
这 3 种颜色有时也称为“通道”或“色带”。
在大多数编程语言(包括 Python)中,有关这 3 个频段的信息通常以以下 2 种方式之一指定:tupleRGB 值或十六进制代码。
在第一种表示法中,我们将颜色表示为 3 个值的元组,分别对应于红色、绿色和蓝色强度,按该顺序(除非另有说明)。此表示形式中的数字(范围从 0 到 255)以十进制(基数 10)编码表示。
在某些情况下,这些数字也会按比例缩小并指定在 0 到 1 的范围内。
另一方面,十六进制代码是一种以十六进制(基数 16)编码表示相同信息(RGB 值)的方式。
例如,红色元组的 RGB 表示为 (255, 0, 0),而其等效的十六进制代码为“#FF0000”(FF = 16*15 + 15 = 255)。
以下是一些常见颜色及其 RGB 值和相应的十六进制代码:
在终端中打印彩色文本
如果您使用命令行安装了软件包,您可能会遇到在终端上以不同颜色文本显示的特殊说明、警告或错误。
这只是终端上的彩色输出很有帮助的众多情况之一。
Python 的库允许我们以我们选择的颜色打印输出。我们可以使用这些库通过自定义文本的前景和背景来打印彩色文本和彩色块。
让我们看一个这样的库——termcolor
.
from termcolor import colored
print("This is a normal text in terminal")
print(colored("This is a colored text in terminal","red"))
print(colored("This is a colored text with background","red","on_green"))
Output:
第一个参数为colored
method 是要打印的文本,后面跟的参数指定文本的前景色和背景色。
还有各种其他库,例如colored, Colr等,允许我们类似地自定义和格式化终端输出。
在 Python 中自定义文本颜色的转义序列
在上一节中,我们使用库来指定文本的前景色和背景色。
我们还可以通过直接附加特殊内容来自定义终端中文本的外观转义序列字符在输出字符串中。
这些转义序列称为“ANSI 序列代码.”
它们用于向终端发出特殊命令,以更改打印在其上的文本的外观。
在本节中,我们将看一些示例,说明如何更改文本的前景色和背景色,以及其他文本格式选项,例如粗体和下划线。
我们使用的所有 ANSI 转义码都以该序列开头'\033['
并结束于'm'
.
让我们看一个例子。
print("\033[0;30;47mHello World")
Output:
请注意,我们不需要调用任何特殊的库来在终端中打印彩色文本。
它只是文本前面的一堆字符(要自定义)定义文本的样式。
上述ANSI代码的格式如下:
\033[
:转义序列字符的开头
0;
:文字样式(0表示无效果)
30;
:文字颜色(30代表黑色)
47;
:背景颜色(47代表白色背景)
m
:表示代码结束,该字符前面定义的样式将应用于其后面的文本。
如果查看之前的输出,白色背景会超出文本末尾延伸到下一个提示。
我们可以通过在文本末尾应用空白样式来避免这种情况。
print("\033[0;30;47mHello World\033[0m")
Output:
我们还可以通过更改转义序列开头后的第一个数字字符来查看一些文本格式选项,例如粗体、斜体和下划线。
粗体文本的代码为1,下划线的代码为4。斜体的代码为3。
print("\033[4;33m This is an underlined yellow text.\033[0m")
print("\033[1;31;46m This is a bold, red text on a cyan background.\033[0m")
Output:
我们还可以使用 RGB 值指定颜色。
为此,我们必须插入特殊代码,如下所示:
\033[38;2;(r);(g);(b)m
– 用于文本颜色
\033[48;2;(r);(g);(b)m
– 用于文本背景颜色
让我们结合这两种方法来显示“斜体”样式的文本,文本颜色为绿色(0,255,0),背景颜色为灰色(128,128,128);
我们将使用 RGB 值来描述颜色。
print("\033[3;38;2;0;255;0;48;2;128;128;128m This is an italic, green text on a gray background.\033[0m")
Output:
使用 Python 从图像中读取像素颜色
正如我们之前讨论的,每种颜色都可以使用 3 个值(即 R、G 和 B 值)的元组来描述。
图像由大量像素组成。像素就像一个生物细胞——它是图像中最小的不可分割的区域。
在彩色图像中,每个像素都是图像上的一个正方形区域,由我们用来定义颜色的三个 RGB 值定义。
这些值表示图像上像素位置的颜色。
由于数字图像是矩形的,因此它作为 3 个二维数组的组合存储在内存中。
每个数组的大小相同(等于图像的大小),它们被称为图像的 R、G 和 B“通道”。
我们可以使用 Python 来表示图像NumPy 数组.
因此,我们可以访问图像中的每个像素并获取它们的 RGB 值。
让我们考虑以下猫的图像。
我很好奇这只猫的眼睛的颜色,你也想知道它是什么颜色吗?
我们可以使用简单的数组索引找到图像中任何位置的颜色(RGB 值)。
首先,我们需要读取图像并将其转换为 NumPy 数组。
from PIL import Image
import numpy as np
img = Image.open("cat.jpg")
img_arr = np.array(img)
print("type =",type(img_arr))
print("shape =",img_arr.shape)
Output:
数组的形状表示图像的高度为 480 像素,宽度为 570 像素。
第三个维度 3 表示它是 RGB 图像。
现在我们想要计算出猫的左眼和右眼颜色的 RGB 值。
我们可以通过索引图像数组对象来做到这一点。我们可以索引两只眼睛区域中的任何位置。
对于左眼,我们将查看位置 [250,260],对于右眼,我们将查看位置 [244,357]。
left_eye_color = img_arr[250,260]
right_eye_color = img_arr[244,357]
print("left eye color = ", left_eye_color)
print("right eye color = ", right_eye_color)
Output:
左眼的 RGB 值确实对应于棕色的黄色阴影,右眼的 RGB 值对应于蓝色的阴影。
修改图像中的像素颜色
现在我们知道如何访问图像中任何位置的像素值,让我们看看如何修改它们以在这些位置绘制新颜色。
让我们尝试在我们用来访问左眼像素值的位置周围插入一个 5×5 的黑色斑点。
我们将使用 pyplot 来执行此操作:
for i in range(248,253):
for j in range(258,263):
img_arr[i, j ] = (0,0,0)
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(111)
ax.axis("off")
ax.imshow(img_arr)
plt.show()
Output:
请注意,由于 for 循环中的像素操作步骤,左眼中的小区域被涂成黑色。
使用 ColorThief 检测图像中的颜色
存在一个有趣的 Python 库,名为“colorthief
'这有助于我们识别图像中最主要的颜色。
让我们找出这张早餐图片中的主色:
from colorthief import ColorThief
img = ColorThief("breakfast.jpg")
dominant_color = img.get_color()
print("Dominant color =",dominant_color)
Output:
The get_color()
方法返回图像中最主要颜色的 RGB 值。
让我们绘制这个颜色。
#plotting the color
im = np.array(dominant_color).reshape(1,1,3)
fig = plt.figure(figsize=(3,3))
ax = fig.add_subplot(111)
ax.axis("off")
ax.imshow(im)
plt.show()
Output:
所以最主要的颜色是浅棕色,这可能来自于放早餐的桌子。
同样,ColorThief 库还可以帮助我们找到调色板或图像中的“前 n 种颜色”。
palette = img.get_palette(color_count=5)
palette = np.array(palette)
print(palette)
Output:
The get_palette
方法接受参数color_count
,它表示我们想要在图像中找到多少种顶级颜色。
让我们绘制这 5 张图像,并将其与上面的早餐图像联系起来。
from skimage import io
ind = np.linspace(0,4,5, dtype=int).reshape(1,5)
fig = plt.figure(figsize=(8,2))
ax = fig.add_subplot(111)
ax.imshow(palette[ind])
ax.set_yticks([])
plt.show()
Output:
现在我们的盘子、浆果和果汁也都出现在调色板中了。
Python颜色模块
蟒蛇的colour
module 是一个简单但功能强大的库,用于存储、转换和操作颜色。
使用这个库,我们可以以多种格式之一存储颜色,即 RGB、十六进制代码、HSL 等。
我们还可以将颜色从一种格式转换为另一种格式。
让我们看一个例子。
from colour import Color
c1 = Color("red")
print("c1 represents",c1)
rgb = c1.rgb
rgb = [int(x*255) for x in rgb]
print("rgb for c1 =",rgb)
print("hex for c1 =",c1.hex_l)
print("hsl for c1 =",c1.hsl)
Output:
属性.rgb
返回 (0,1) 范围内的十进制值,因此我们通过将它们分别乘以 255 将它们转换为 (0,255) 范围。
现在让我们看看修改现有颜色的步骤。
c1.green = 1.0
print("c1 now represents the color",c1)
#Manipulating HSL channels
print("hsl for c1 currently is",c1.hsl)
c1.hue = 0.666666667
print("c1 is now", c1)
Output:
请注意,通过操纵绿色通道值,我们如何将现有的红色颜色变成黄色。
然后,通过修改其色调值,我们将黄色转换为蓝色。
使用颜色模块创建渐变颜色
渐变是连续的颜色图或两种或多种颜色之间的连续渐变。
我们可以使用以下方法生成两种颜色之间的渐变colour
module.
让我们创建红色和绿色之间的渐变。
c1 = Color("red")
c2 = Color("green")
gradient = list(c1.range_to(c2, 10))
print(gradient)
Output:
这会生成红色和绿色之间的 10 种颜色。
让我们尝试将它们形象化。
grad_rgb = [x.rgb for x in gradient]
grad_rgb_255 = [list(map(lambda x: int(x*255), i)) for i in grad_rgb]
palette = np.array(grad_rgb_255)
import matplotlib.pyplot as plt
ind = np.linspace(0,9,10, dtype=int).reshape(1,10)
fig = plt.figure(figsize=(8,2))
ax = fig.add_subplot(111)
ax.imshow(palette[ind])
ax.axis("off")
plt.show()
Output:
这显示了红色和绿色之间的渐变,由 10 种连续颜色定义。
我们可以通过在两者之间生成越来越多的颜色来使渐变更加平滑。
结论
在本教程中,我们学习了如何表示、操作颜色,以及如何使用 Python 中的各种库将它们应用于文本和其他对象。
我们首先了解计算机程序中表示颜色的一些方法。
然后我们研究了如何修改终端中文本的外观。
首先,我们通过使用 Python 库,然后将转义序列字符附加到输出字符串来完成此操作。
我们探索了读取和更新图像中任何位置的像素颜色的方法。
我们还查看了一个库来查找图像中最主要的颜色。
接下来,我们研究了用于表示颜色并更新现有颜色的“颜色”模块。
我们最终通过使用颜色模块生成颜色渐变,然后在 matplotlib 库的帮助下绘制相同的颜色来结束它。