📜  Python – 使用 Pillow 进行颜色反转

📅  最后修改于: 2022-05-13 01:55:14.836000             🧑  作者: Mango

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)。