图像数据的可视化是理解数据、调试算法和展示结果的关键步骤,Matplotlib作为Python生态中最基础也最灵活的可视化库,提供了完整的图像加载、显示、调整和分析工具链。
数字图像在计算机中以多维数组的形式存储,理解这种数据结构是可视化的基础:
(高度, 宽度)
),每个元素表示像素的亮度(0-255或0-1)(高度, 宽度, 3)
),最后一维分别对应红、绿、蓝三个通道(高度, 宽度, 4)
),增加了Alpha通道(透明度)Matplotlib的imshow()
函数是图像可视化的核心工具,它能将数组数据转换为可视化图像。
Matplotlib本身不提供图像读取功能,通常结合PIL
或skimage
库加载图像,也可直接使用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)
使用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()
若要显示灰度图,需将彩色图转换为单通道,或指定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()
分别显示红、绿、蓝三个通道的图像,观察色彩构成:
# 提取三个通道
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()
通过像素值的线性变换调整图像亮度和对比度,并用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()
除了默认的viridis
和gray
,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
:均匀感知的配色(推荐)plasma
、inferno
:适合突出高值区域coolwarm
:正负对比鲜明(适合差值图像)通过直方图分析图像的亮度分布,辅助判断曝光是否正常:
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()
在图像处理算法(如滤波、边缘检测)中,常需对比处理前后的效果:
以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()
在目标检测或图像分割中,可在图像上标注边界框或掩码:
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()
uint8
类型(0-255),避免float
类型导致显示异常float
数组,需归一化到0-1范围resized_img = Image.fromarray(img_array).resize((600, 400))
plt.imshow(resized_img)
bbox_inches='tight'
去除白边:plt.savefig("result.png", dpi=300, bbox_inches='tight')
总结:Matplotlib图像处理的核心能力
- 快速查看和验证图像数据的加载与处理结果
- 对比不同算法或参数的效果(如滤波、增强、检测)
- 分析图像的像素分布特征(亮度、色彩通道)
- 标注关键区域,使结果展示更直观
That’s all, thanks for reading~~
觉得有用就点个赞
、收进收藏
夹吧!关注
我,获取更多干货~