高级图表:图像处理与显示

Matplotlib 不仅可以绘制统计图表,还提供了强大的图像显示和处理功能。 通过 plt.imshow() 可以轻松显示数组形式的图像数据,并结合颜色映射、插值等方法进行可视化。 本章将带你掌握 Matplotlib 中图像显示的核心技巧。

📸 1. 读取和显示图像

使用 plt.imread() 读取图像文件(支持 PNG、JPG 等格式),返回 NumPy 数组,然后用 plt.imshow() 显示:

import matplotlib.pyplot as plt
import numpy as np

# 读取图像(请确保路径正确)
img = plt.imread('example.jpg')  # 返回形状为 (height, width, channels) 的数组

plt.imshow(img)
plt.title('原始图像')
plt.axis('off')  # 关闭坐标轴
plt.show()
✔️ 如果图像是 RGBA 四通道,imshow 会自动处理。

🌈 2. 自定义颜色映射

对于单通道数据(如灰度图或二维数组),可以通过 cmap 参数指定颜色映射,将数值映射到颜色:

# 生成一个渐变数组
x = np.linspace(0, 10, 100)
y = np.linspace(0, 10, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)

plt.imshow(Z, cmap='viridis', origin='lower', extent=[0,10,0,10])
plt.colorbar(label='值')
plt.title('颜色映射示例 (viridis)')
plt.show()
✔️ extent 定义坐标轴范围,origin 控制原点位置。

⚫ 3. 显示灰度图像

对于二维灰度数组,可以使用 cmap='gray' 显示为灰度图:

# 读取图像并转换为灰度(假设为RGB)
img_color = plt.imread('example.jpg')
# 转为灰度:取RGB均值(简单方法)
img_gray = np.mean(img_color[:,:,:3], axis=2)

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

🔴🟢🔵 4. 图像通道操作

可以分离和显示 RGB 各个通道,或修改通道值:

# 假设 img 是 RGB 图像
r = img[:,:,0]  # 红色通道
g = img[:,:,1]  # 绿色通道
b = img[:,:,2]  # 蓝色通道

plt.figure(figsize=(12,3))
plt.subplot(1,4,1); plt.imshow(img); plt.title('原图'); plt.axis('off')
plt.subplot(1,4,2); plt.imshow(r, cmap='Reds'); plt.title('红色通道'); plt.axis('off')
plt.subplot(1,4,3); plt.imshow(g, cmap='Greens'); plt.title('绿色通道'); plt.axis('off')
plt.subplot(1,4,4); plt.imshow(b, cmap='Blues'); plt.title('蓝色通道'); plt.axis('off')
plt.tight_layout()
plt.show()

🔍 5. 图像插值方法

imshowinterpolation 参数控制图像放大或缩小时的像素插值方式,影响显示效果:

# 创建一个小图像(8x8)
small_img = np.random.rand(8,8)

plt.figure(figsize=(12,4))
plt.subplot(1,4,1); plt.imshow(small_img, interpolation='nearest', cmap='viridis')
plt.title('nearest'); plt.axis('off')
plt.subplot(1,4,2); plt.imshow(small_img, interpolation='bilinear', cmap='viridis')
plt.title('bilinear'); plt.axis('off')
plt.subplot(1,4,3); plt.imshow(small_img, interpolation='bicubic', cmap='viridis')
plt.title('bicubic'); plt.axis('off')
plt.subplot(1,4,4); plt.imshow(small_img, interpolation='lanczos', cmap='viridis')
plt.title('lanczos'); plt.axis('off')
plt.tight_layout()
plt.show()
✔️ nearest 显示像素块,bicubic 更平滑。

💾 6. 保存图像

使用 plt.savefig() 保存显示的图像,也可以通过 imsave(matplotlib.image 模块)直接保存数组为图像文件:

import matplotlib.image as mpimg

# 方法一:保存当前 figure
plt.imshow(img)
plt.axis('off')
plt.savefig('output.png', dpi=300, bbox_inches='tight')

# 方法二:直接保存数组
mpimg.imsave('output.jpg', img, dpi=300)  # 注意:JPG 可能不支持透明度

🔄 7. 图像变换(结合 NumPy/SciPy)

可以结合 NumPy 进行简单变换,如旋转、翻转:

# 图像翻转
img_flip_ud = np.flipud(img)   # 上下翻转
img_flip_lr = np.fliplr(img)   # 左右翻转

# 图像旋转(使用 scipy.ndimage)
from scipy import ndimage
img_rotated = ndimage.rotate(img, 45, reshape=False)  # 45度旋转

plt.figure(figsize=(12,4))
plt.subplot(1,3,1); plt.imshow(img_flip_ud); plt.title('上下翻转'); plt.axis('off')
plt.subplot(1,3,2); plt.imshow(img_flip_lr); plt.title('左右翻转'); plt.axis('off')
plt.subplot(1,3,3); plt.imshow(img_rotated); plt.title('旋转45°'); plt.axis('off')
plt.tight_layout()
plt.show()

🖼️ 8. 显示多幅图像

使用 subplots 创建网格,在每个子图中显示图像:

fig, axes = plt.subplots(2, 3, figsize=(10, 6))

# 假设有6张图像(这里用随机噪声代替)
for i, ax in enumerate(axes.flat):
    random_img = np.random.rand(64,64)
    ax.imshow(random_img, cmap='viridis')
    ax.set_title(f'图像{i+1}')
    ax.axis('off')

plt.tight_layout()
plt.show()

📊 9. 图像直方图均衡化(示例)

结合 NumPy 对灰度图像进行直方图均衡化,增强对比度:

# 计算累积分布函数并映射
def histeq(img, n_bins=256):
    hist, bins = np.histogram(img.flatten(), n_bins, density=True)
    cdf = hist.cumsum()  # 累积分布
    cdf = cdf / cdf[-1]  # 归一化
    # 线性插值映射
    img_equalized = np.interp(img.flatten(), bins[:-1], cdf)
    return img_equalized.reshape(img.shape)

# 对灰度图应用
img_gray_eq = histeq(img_gray)

plt.figure(figsize=(8,4))
plt.subplot(1,2,1); plt.imshow(img_gray, cmap='gray'); plt.title('原灰度图'); plt.axis('off')
plt.subplot(1,2,2); plt.imshow(img_gray_eq, cmap='gray'); plt.title('均衡化后'); plt.axis('off')
plt.show()

🔮 10. 透明度与图像叠加

使用 alpha 参数控制透明度,实现图像叠加:

# 创建两张图像
img1 = np.random.rand(100,100)
img2 = np.random.rand(100,100)

plt.imshow(img1, cmap='Reds', alpha=0.7)
plt.imshow(img2, cmap='Blues', alpha=0.5)
plt.title('图像叠加')
plt.colorbar()
plt.show()

🎨 11. 常用颜色映射表

Matplotlib 提供了丰富的颜色映射,适用于不同类型的数据:

  • 顺序映射:'viridis', 'plasma', 'inferno', 'magma', 'cividis'(适合连续数据)
  • 发散映射:'coolwarm', 'RdBu', 'PiYG'(适合有中心值的数据)
  • 循环映射:'twilight', 'hsv'(适合角度数据)
  • 定性映射:'tab10', 'Set3'(适合分类数据)
提示: 可以使用 plt.colormaps() 查看所有可用颜色映射。

图像显示是 Matplotlib 中非常实用的功能,掌握 imshow 的各项参数,你可以灵活地展示科学数据、照片或处理结果。下一章我们将学习子图布局的高级技巧,让你能更自由地组织多幅图表。