Python – 使用 Pillow 进行颜色反转
颜色反转(图像负片)是反转图像像素值的方法。图像反转不依赖于图像的颜色模式,即反转在通道级别上起作用。当在多色图像(RGB、CMYK 等)上使用反转时,每个通道都会单独处理,如果通过调用所有通道的结果来形成最终结果。
我们将使用枕头(PIL)库来获取图像的负片。要安装库,请在命令行中执行以下命令:-
pip install pillow
注意:一些 Linux 发行版倾向于预装Python和 PIL。
在本文中,描述了两种反转图像色彩空间的方法。第一个是使用 ImageChops.invert()函数的内置方法。在第二个中,我们将通过逐元素减去像素值来反转图像。
示例图像 -
方法#1:
使用内置方法 ImageChops.invert() 否定颜色。
Python3
# Importing imagechops for using the invert() method
from PIL import Image, ImageChops
# Opening the test image, and saving it's object
img = Image.open('test.jpg')
# Passing the image object to invert()
inv_img = ImageChops.invert(img)
# Displaying the output image
inv_img.show()
Python3
from PIL import Image
# numpy for performing batch processing and elementwise
# matrix operations efficiently
import numpy as np
# Opening an image, and saving open image object
img = Image.open(r"sample.jpg")
# Creating an numpy array out of the image object
img_arry = np.array(img)
# Maximum intensity value of the color mode
I_max = 255
# Subtracting 255 (max value possible in a given image
# channel) from each pixel values and storing the result
img_arry = I_max - img_arry
# Creating an image object from the resultant numpy array
inverted_img = Image.fromarray(img_arry)
# Saving the image under the name Image_negative.jpg
inverted_img.save(r"Image_negative.jpg")
输出:
解释:
首先我们导入 ImageChops 模块以使用 invert() 方法。然后我们打开测试图像(test.jpg),并保存它的图像对象。现在我们将该图像对象传递给 ImageDraw.invert() ,它返回反转图像。最后,我们显示了颜色反转的图像。
使用 ImageChops.invert() 时要记住的事项:
- 输入图像不应包含 Alpha 通道
- 输入图像不应为 P(调色板)颜色模式。
方法#2:
用于获得图像反转的方法是用当前像素的值减去一个像素的最大值/强度。结果值由公式指导 -
其中 INV 是生成的反转像素,I^MAX 是给定颜色模式下的最大强度级别,I(x, y) 是图像/颜色通道在特定坐标对处的强度(像素值)。
Python3
from PIL import Image
# numpy for performing batch processing and elementwise
# matrix operations efficiently
import numpy as np
# Opening an image, and saving open image object
img = Image.open(r"sample.jpg")
# Creating an numpy array out of the image object
img_arry = np.array(img)
# Maximum intensity value of the color mode
I_max = 255
# Subtracting 255 (max value possible in a given image
# channel) from each pixel values and storing the result
img_arry = I_max - img_arry
# Creating an image object from the resultant numpy array
inverted_img = Image.fromarray(img_arry)
# Saving the image under the name Image_negative.jpg
inverted_img.save(r"Image_negative.jpg")
输出:
解释:
首先,我们将 numpy 导入到我们的代码中,因为 numpy 允许对矩阵进行快速的元素运算,并提供对数组的多种算术运算。然后我们使用 Image.open() 打开测试图像,并将返回的图像对象存储在变量 img 中。然后我们根据从打开的图像对象 (img) 获得的像素值创建一个数组 (img_arry)。这样做是为了允许 numpy 库提供的元素减法运算。现在我们从每个通道/像素值中减去 255,这将导致所有像素值被反转。现在,我们使用这个结果矩阵来创建一个新图像(inverted_img)。最后,我们将图像保存在 Image_negative.jpg 的名称下。
有些事情要记住——
- 应确保输入图像不包含 Alpha 通道。这是因为当行 img_arry = 255 – img_arry 将对包含 alpha 通道的图像执行时,它也会反转 alpha 通道值。这会导致输出图像不一致,因为我们最终可能会得到完全透明的图像(这不是颜色反转的一部分)。允许处理 RGBA 图像的一种方法是首先使用 Image.convert('RGB') 将它们转换为 RGB 颜色模式。或者,我们可以使用 Image.getdata(band=3) 提取 alpha 通道,然后将其组合到最终图像以获取原始 RGBA 图像。
此输入图像 sample.jpg 是有意选择 .jpg 格式的,因为JPG/JPEG图像格式不支持透明度或 Alpha 通道。 - 输入图像不应为 P(调色板)模式。由于调色板图像不包含坐标处的像素值,而是对属于颜色图(不同大小)的像素值的索引。因此,图像反演会导致结果不一致。
- 假设在特定图像模式下可实现的最大强度为 255,则分配值 I_max = 255。该值不是硬编码的。该值取决于颜色模式,因此可能小于 255(例如,在二值图像中为 1)或大于 255(例如,在 16 位无符号灰度模式中为 32536)。