Matplotlib-图像处理与可视化

Matplotlib-图像处理与可视化

    • 一、图像数据的本质:从数组到像素
    • 二、基础操作:加载与显示图像
      • 1. 加载图像数据
      • 2. 显示单张图像
      • 3. 显示灰度图像
    • 三、进阶可视化:通道分离与色彩调整
      • 1. 分离RGB通道
      • 2. 调整亮度与对比度
    • 四、实用技巧:色彩映射与像素值分析
      • 1. 自定义色彩映射(Colormap)
      • 2. 像素值分布直方图
    • 五、多图对比与标注:算法结果可视化
      • 1. 边缘检测结果对比
      • 2. 图像标注:突出感兴趣区域
    • 六、注意事项与性能优化
      • 1. 图像数据类型
      • 2. 大图像显示优化
      • 3. 保存高质量图像

图像数据的可视化是理解数据、调试算法和展示结果的关键步骤,Matplotlib作为Python生态中最基础也最灵活的可视化库,提供了完整的图像加载、显示、调整和分析工具链。

一、图像数据的本质:从数组到像素

数字图像在计算机中以多维数组的形式存储,理解这种数据结构是可视化的基础:

  • 灰度图:二维数组((高度, 宽度)),每个元素表示像素的亮度(0-255或0-1)
  • RGB彩色图:三维数组((高度, 宽度, 3)),最后一维分别对应红、绿、蓝三个通道
  • RGBA图像:三维数组((高度, 宽度, 4)),增加了Alpha通道(透明度)

Matplotlib的imshow()函数是图像可视化的核心工具,它能将数组数据转换为可视化图像。

二、基础操作:加载与显示图像

1. 加载图像数据

Matplotlib本身不提供图像读取功能,通常结合PILskimage库加载图像,也可直接使用NumPy数组创建图像:

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image  # 用于读取图像

# 方法1:从本地文件加载
img = Image.open("test_image.jpg")  # 读取图像
img_array = np.array(img)  # 转换为NumPy数组(形状:(H, W, 3))

# 方法2:创建随机测试图像
random_img = np.random.randint(0, 256, size=(200, 300, 3), dtype=np.uint8)

2. 显示单张图像

使用plt.imshow()显示图像,配合plt.axis('off')去除坐标轴:

plt.figure(figsize=(8, 6))
plt.imshow(img_array)  # 显示图像
plt.axis('off')  # 关闭坐标轴
plt.title("Original Image", fontsize=12)
plt.show()

3. 显示灰度图像

若要显示灰度图,需将彩色图转换为单通道,或指定cmap参数:

# 转换为灰度图(加权平均法)
gray_img = np.dot(img_array[..., :3], [0.2989, 0.5870, 0.1140]).astype(np.uint8)

plt.figure(figsize=(8, 6))
plt.imshow(gray_img, cmap='gray')  # cmap='gray'指定灰度配色
plt.axis('off')
plt.title("Grayscale Image", fontsize=12)
plt.show()

三、进阶可视化:通道分离与色彩调整

1. 分离RGB通道

分别显示红、绿、蓝三个通道的图像,观察色彩构成:

# 提取三个通道
red_channel = img_array[:, :, 0]
green_channel = img_array[:, :, 1]
blue_channel = img_array[:, :, 2]

# 创建子图
fig, axes = plt.subplots(1, 4, figsize=(16, 4))

axes[0].imshow(img_array)
axes[0].set_title("Original")
axes[1].imshow(red_channel, cmap='Reds')  # 红色通道用红色系配色
axes[1].set_title("Red Channel")
axes[2].imshow(green_channel, cmap='Greens')
axes[2].set_title("Green Channel")
axes[3].imshow(blue_channel, cmap='Blues')
axes[3].set_title("Blue Channel")

# 关闭所有坐标轴
for ax in axes:
    ax.axis('off')

plt.tight_layout()
plt.show()

2. 调整亮度与对比度

通过像素值的线性变换调整图像亮度和对比度,并用Matplotlib对比效果:

def adjust_brightness_contrast(img, brightness=0, contrast=1.0):
    """调整亮度(brightness)和对比度(contrast)"""
    adjusted = contrast * img + brightness
    return np.clip(adjusted, 0, 255).astype(np.uint8)  # 裁剪到0-255

# 调整参数
bright_img = adjust_brightness_contrast(img_array, brightness=50)
dark_img = adjust_brightness_contrast(img_array, brightness=-50)
high_contrast = adjust_brightness_contrast(img_array, contrast=1.5)
low_contrast = adjust_brightness_contrast(img_array, contrast=0.5)

# 对比显示
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
axes[0, 0].imshow(bright_img); axes[0, 0].set_title("Bright +50")
axes[0, 1].imshow(dark_img); axes[0, 1].set_title("Bright -50")
axes[1, 0].imshow(high_contrast); axes[1, 0].set_title("Contrast ×1.5")
axes[1, 1].imshow(low_contrast); axes[1, 1].set_title("Contrast ×0.5")

for ax in axes.flat:
    ax.axis('off')

plt.tight_layout()
plt.show()

四、实用技巧:色彩映射与像素值分析

1. 自定义色彩映射(Colormap)

除了默认的viridisgray,Matplotlib提供多种配色方案,适合不同场景:

# 显示热图风格的灰度图
plt.figure(figsize=(8, 6))
plt.imshow(gray_img, cmap='hot')  # 热图配色
plt.colorbar(label="Pixel Intensity")  # 添加颜色条
plt.axis('off')
plt.title("Grayscale Image with 'hot' Colormap", fontsize=12)
plt.show()

常用配色方案:

  • jet:传统彩虹色(但可能误导数据分布)
  • viridis:均匀感知的配色(推荐)
  • plasmainferno:适合突出高值区域
  • coolwarm:正负对比鲜明(适合差值图像)

2. 像素值分布直方图

通过直方图分析图像的亮度分布,辅助判断曝光是否正常:

plt.figure(figsize=(10, 4))

# 绘制RGB通道直方图
plt.subplot(1, 2, 1)
for i, color in enumerate(['r', 'g', 'b']):
    plt.hist(img_array[:, :, i].ravel(), bins=256, color=color, alpha=0.5)
plt.title("RGB Channel Histograms")
plt.xlabel("Pixel Value")
plt.ylabel("Frequency")

# 绘制灰度图直方图
plt.subplot(1, 2, 2)
plt.hist(gray_img.ravel(), bins=256, color='gray', alpha=0.7)
plt.title("Grayscale Histogram")
plt.xlabel("Pixel Value")
plt.ylabel("Frequency")

plt.tight_layout()
plt.show()

五、多图对比与标注:算法结果可视化

在图像处理算法(如滤波、边缘检测)中,常需对比处理前后的效果:

1. 边缘检测结果对比

以Sobel边缘检测为例,对比原图与边缘图:

from scipy import ndimage  # 用于边缘检测

# 计算水平和垂直边缘
sobel_x = ndimage.sobel(gray_img, axis=0)  # 水平边缘
sobel_y = ndimage.sobel(gray_img, axis=1)  # 垂直边缘
sobel_edges = np.hypot(sobel_x, sobel_y)  # 合成边缘图
sobel_edges = (sobel_edges / sobel_edges.max() * 255).astype(np.uint8)  # 归一化

# 对比显示
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(gray_img, cmap='gray'); axes[0].set_title("Original Grayscale")
axes[1].imshow(sobel_edges, cmap='gray'); axes[1].set_title("Sobel Edges")

for ax in axes:
    ax.axis('off')

plt.tight_layout()
plt.show()

2. 图像标注:突出感兴趣区域

在目标检测或图像分割中,可在图像上标注边界框或掩码:

plt.figure(figsize=(8, 6))
plt.imshow(img_array)

# 绘制边界框(x1, y1)到(x2, y2)
x1, y1, x2, y2 = 100, 80, 200, 180
plt.gca().add_patch(plt.Rectangle(
    (x1, y1), x2 - x1, y2 - y1,
    fill=False, edgecolor='red', linewidth=2
))

# 添加文本标注
plt.text(x1, y1 - 10, "Target", color='red', fontweight='bold')
plt.axis('off')
plt.title("Image with Bounding Box", fontsize=12)
plt.show()

六、注意事项与性能优化

1. 图像数据类型

  • 确保图像数组为uint8类型(0-255),避免float类型导致显示异常
  • 若使用float数组,需归一化到0-1范围

2. 大图像显示优化

  • 显示高分辨率图像时,先缩小尺寸:
    resized_img = Image.fromarray(img_array).resize((600, 400))
    plt.imshow(resized_img)
    

3. 保存高质量图像

  • 保存图像时使用bbox_inches='tight'去除白边:
    plt.savefig("result.png", dpi=300, bbox_inches='tight')
    

总结:Matplotlib图像处理的核心能力

  1. 快速查看和验证图像数据的加载与处理结果
  2. 对比不同算法或参数的效果(如滤波、增强、检测)
  3. 分析图像的像素分布特征(亮度、色彩通道)
  4. 标注关键区域,使结果展示更直观

That’s all, thanks for reading~~
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~

你可能感兴趣的:(Matplotlib-图像处理与可视化)