Pillow 基础图像操作与数据预处理

Pillow 基础图像操作与数据预处理

图像的读取、显示、保存、裁剪、旋转与缩放,是所有高级图像分析任务的基础。这些看似简单的操作,实际上构成了特征提取、图像增强、以及机器学习模型输入准备的核心步骤。只有从最初的像素数据开始,理解图像在计算机中的表达方式,才能真正掌握数据分析与建模中的“图像底层逻辑”。

在图像分析和机器学习任务中,数据预处理的质量往往决定了最终结果的好坏。通过科学的预处理手段,可以有效提升输入数据的均衡性与鲁棒性,从而提高模型的泛化能力。本篇文章将带你系统掌握 Pillow 的基础图像操作与数据预处理技巧,从文件读取到数据转化的全过程,一步步构建完整的图像处理链条。


1. 图像读取与显示

1.1 打开图像

Pillow 提供了直观的图像加载方式。使用 Image.open() 函数即可打开图像文件。

下面以 scikit-image 库自带的经典“宇航员”图为例:

from PIL import Image
from skimage import data

# 使用 scikit-image 的示例图片
img_array = data.astronaut()  # 经典“宇航员”示例图
img = Image.fromarray(img_array)

# 输出图像信息
print('format: {}\nsize: {}\nmode: {}'.format(
    img.format, img.size, img.mode
))

运行后可看到图像的基本属性,包括格式、尺寸与颜色模式:

format: None
size: (512, 512)
mode: RGB

format: 文件格式(如 JPEG、PNG)

size: 图像宽高(像素)

mode: 颜色模式(如 RGB、L、RGBA)

这说明该图像为标准 RGB 彩色图像,宽高均为 512 像素。

1.2 显示图像

在不同环境中显示图像的方式略有不同:

img.show()

在这里插入图片描述

该方法会打开系统自带的图片查看器。

如果你在 Jupyter Notebook 中运行,则推荐:

from IPython.display import display
display(img)

在这里插入图片描述

你将看到一张清晰的宇航员照片(RGB 彩色),适合后续图像操作实验。


2. 图像保存与格式转换

读取后的图像可通过 save() 方法保存为新文件。

2.1 保存为新文件

下面的示例将图像保存为 PNG 文件:

img.save('output.png')

在这里插入图片描述

同样也可以调整保存格式与参数。例如,将图像保存为 JPEG 格式,并设定较高的质量参数:

img.save('output.jpg', quality=90)

在这里插入图片描述

quality 参数仅对 JPEG 有效,控制压缩质量(0–100,默认 75)。

数值越大,文件体积越大但图像更清晰。

2.2 格式转换

当目标格式不支持透明通道(如 JPEG),需先将图像转换为 RGB 模式:

img.convert('RGB').save('converted.jpg')

在这里插入图片描述

若目标格式不支持透明度(如 JPEG),需先转为 RGB 模式。


3. 几何变换:裁剪、旋转与缩放

这些是最常见的图像几何变换操作。

3.1 图像裁剪

图像几何操作是最直观的预处理方式。使用 crop() 方法可以截取特定区域(左、上、右、下),例如::

box = (100, 100, 400, 400)
cropped = img.crop(box)

display(cropped)

在这里插入图片描述

此处 box 参数定义了裁剪矩形的左、上、右、下边界,输出的结果是一幅截取后的局部图像。

3.2 图像旋转

当我们想让图像朝某个角度旋转时,可以使用 rotate() 方法。参数为旋转角度(单位为度):

rotated1 = img.rotate(45)

display(rotated1)

在这里插入图片描述

expand=True 的设置确保旋转后的图像不会被裁剪,使得完整图像得以保留。

rotated2 = img.rotate(45, expand=True)

display(rotated2)

在这里插入图片描述

3.3 图像缩放

若要调整图像的尺寸,可使用 resize() 函数指定目标大小,例如将其缩小为 300×200 像素:

resized = img.resize((300, 200))
resized.show()

在这里插入图片描述

或按比例缩放:

w, h = img.size
scaled = img.resize((int(w*0.5), int(h*0.5)))

display(scaled)

在这里插入图片描述

在缩放时,可选参数如 Image.BILINEARImage.ANTIALIAS 可以帮助提升插值质量,使结果更加平滑自然。


4. 图像模式与通道

图像的“模式”决定了其数据结构。RGB 图像包含三个通道,而灰度图仅有一个。

4.1 查看图像模式

通过 img.mode 可查看当前模式,convert() 方法则用于模式转换。例如:

print(img.mode)
RGB

常见模式包括:

模式含义通道数
L灰度图1
RGB真彩色3
RGBA含透明通道4
CMYK印刷色彩模式4

4.2 模式转换

gray = img.convert('L')
gray.show()

在这里插入图片描述

上述代码将彩色图像转为灰度图,其视觉效果更简洁,常用于特征提取或边缘检测任务。

若需要用于印刷或 CMYK 色彩空间的任务,可使用:

cmyk = img.convert('CMYK')

print(cmyk.mode)
CMYK

每个模式代表着不同的应用场景。RGB 用于显示设备,CMYK 常见于印刷出版,而 RGBA 额外包含透明度信息。

4.3 拆分与合并通道

Pillow 允许直接拆分通道以便单独分析:

r, g, b = img.split()  # 拆分
merged = Image.merge('RGB', (r, g, b))  # 合并

为了更直观地理解三个通道的作用,可以通过 matplotlib 将它们分别可视化:

from PIL import Image
from skimage import data
import matplotlib.pyplot as plt
import seaborn as sns

sns.set_theme(style="whitegrid", font="SimHei", rc={"axes.unicode_minus": False})

# 加载示例图像
img = Image.fromarray(data.astronaut())

# 拆分 RGB 通道
r, g, b = img.split()

# 可视化展示
fig, axes = plt.subplots(1, 3, figsize=(16, 5))

# 将单通道转为彩色可视化形式
axes[0].imshow(r, cmap="Reds")
axes[0].set_title("红色通道 (R)")
axes[0].axis("off")

axes[1].imshow(g, cmap="Greens")
axes[1].set_title("绿色通道 (G)")
axes[1].axis("off")

axes[2].imshow(b, cmap="Blues")
axes[2].set_title("蓝色通道 (B)")
axes[2].axis("off")

plt.tight_layout()
plt.show()

在这里插入图片描述

可以清晰地看到红、绿、蓝三种通道对整体图像色彩的贡献。拆分后的通道也能重新组合回完整图像:

merged = Image.merge('RGB', (r, g, b))

display(merged)

在这里插入图片描述

这证明图像的彩色信息实质上是多个单通道数据叠加的结果。


5. 批量图像处理

在深度学习或大规模图像分析任务中,往往需要对整个文件夹中的图像执行统一的操作。Pillow 的接口设计非常简洁,能够方便地完成批处理。例如,下面的代码将一个目录中的所有图片缩放至 256×256 像素,并统一转换为灰度图:

在这里插入图片描述

import os
from PIL import Image

# 定义输入与输出文件夹路径
input_dir = 'images/'       # 原始图片所在目录
output_dir = 'processed/'   # 处理后图片保存目录

# 如果输出目录不存在则自动创建
os.makedirs(output_dir, exist_ok=True)

# 定义要处理的图片扩展名集合
valid_exts = ('.jpg', '.png', '.bmp')

# 遍历输入文件夹中的所有文件
for file in os.listdir(input_dir):
    # 判断文件扩展名是否符合要求
    if file.lower().endswith(valid_exts):
        # 构建文件路径
        file_path = os.path.join(input_dir, file)

        # 打开图像文件
        img = Image.open(file_path)

        # 调整图像尺寸为256x256像素
        resized = img.resize((256, 256))

        # 将图像转换为灰度模式(L表示8位灰度)
        gray = resized.convert('L')

        # 构建输出文件路径并保存
        output_path = os.path.join(output_dir, file)
        gray.save(output_path)

        # 打印处理进度
        print(f"已处理: {file}")

在这里插入图片描述

所有图片统一缩放为 256×256;

转为灰度图;

保存到 processed 文件夹中。

这段脚本能自动遍历整个文件夹并完成批量预处理。执行后,你将得到格式统一、尺寸一致的图像数据集,这对于后续特征提取与模型训练至关重要。


6. 图像数据与 NumPy 的融合

Pillow 图像与 NumPy 数组可以无缝互转,从而实现像素级运算或与深度学习框架(如 TensorFlow、PyTorch)的对接。通过 np.array(img) 可将图像转换为数组:

import numpy as np

array = np.array(img)
print(array.shape)
(512, 512, 3)

输出结果 (512, 512, 3) 表示图像的高、宽与通道数。反向操作也同样简单:

img2 = Image.fromarray(array)
display(img2)

download

这样,Pillow 成为了连接传统图像处理与数值分析的桥梁。你可以使用 NumPy 对像素值进行归一化、滤波或其他矩阵操作,然后再返回到图像空间。


7. 图像归一化与增强准备

在模型训练或特征学习阶段,通常需要将像素值标准化到 [0,1] 区间,以消除亮度差异带来的影响。通过简单的数组运算即可实现:

array = np.array(img) / 255.0

print(array)
[[[0.60392157 0.57647059 0.59215686]
  [0.42745098 0.40392157 0.48627451]
  [0.24705882 0.22745098 0.4       ]
  ...
  [0.49803922 0.47058824 0.45098039]
  [0.47058824 0.45882353 0.41568627]
  [0.49019608 0.46666667 0.43137255]]

 [[0.69411765 0.67058824 0.67058824]
  [0.56470588 0.55294118 0.56078431]
  [0.44313725 0.44705882 0.48627451]
  ...
  [0.49803922 0.4627451  0.43921569]
  [0.48627451 0.45098039 0.42352941]
  [0.4745098  0.45490196 0.41176471]]

 ...

 [[0.71764706 0.6627451  0.66666667]
  [0.71372549 0.65490196 0.67058824]
  [0.7254902  0.64313725 0.69019608]
  ...
  [0.         0.         0.00392157]
  [0.00392157 0.00392157 0.00392157]
  [0.         0.         0.        ]]

 [[0.72156863 0.65490196 0.6745098 ]
  [0.71764706 0.64705882 0.6627451 ]
  [0.70588235 0.63529412 0.67058824]
  ...
  [0.         0.         0.        ]
  [0.00392157 0.00392157 0.00392157]
  [0.         0.         0.        ]]]

归一化后的结果可以被视为浮点型矩阵,方便后续输入神经网络或进行特征统计。若结合图像增强方法(如旋转、翻转、噪声扰动),还可以有效提升模型的泛化能力。

或使用随机翻转、旋转等增强方法:

import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from PIL import Image

# 载入示例图像并转换为数组
img = Image.fromarray(data.astronaut())
array = np.array(img)

# 进行归一化处理:将像素值缩放到 [0, 1] 区间
normalized = array / 255.0

# 可视化原图与归一化结果对比
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
axes[0].imshow(array.astype(np.uint8))
axes[0].set_title("原始图像(像素0-255)")
axes[0].axis("off")

axes[1].imshow(normalized)
axes[1].set_title("归一化后图像(像素0-1)")
axes[1].axis("off")

plt.tight_layout()
plt.show()

download

# 输出示例像素值,观察归一化效果
print("原始像素示例:", array[0, 0])
print("归一化像素示例:", normalized[0, 0])
原始像素示例: [154 147 151]
归一化像素示例: [0.60392157 0.57647059 0.59215686]

经过归一化处理后,原始图像中的每个像素值由 0–255 的整数变为 0–1 的浮点数,这不仅让模型更快收敛,也有助于避免梯度爆炸或消失的问题。


8. 可视化与结果展示

为了方便比对原始与处理后的图像,可使用 Matplotlib:

import matplotlib.pyplot as plt

gray = img.convert('L')

plt.figure(figsize=(8,4))
plt.subplot(1,2,1)
plt.title('原始图像')
plt.imshow(img)
plt.axis('off')

plt.subplot(1,2,2)
plt.title('灰度图像')
plt.imshow(gray, cmap='gray')
plt.axis('off')
plt.show()

download


9. 总结

Pillow 以其简洁的接口和强大的功能,成为 Python 图像处理的基础工具。从读取到保存、从几何变换到通道分解、再到批量化处理与数值融合,它覆盖了图像预处理的全流程。

掌握这些操作,不仅能帮助你更高效地准备数据集,也能让你更深入地理解图像的数学本质与结构特征。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MoRanzhi1203

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值