Python 中的图像预处理是计算机视觉任务的基础步骤,通常包括图像读取、尺寸调整、归一化、噪声去除、增强、格式转换等操作。以下结合常用库(如 OpenCV、PIL/Pillow、NumPy、Matplotlib)详细介绍关键预处理技术及实现代码。
一、图像读取与显示
1. 使用 OpenCV 读取图像
注意:OpenCV 默认以 BGR 格式读取图像,需转换为 RGB 格式以正常显示。
python
import cv2
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread('image.jpg')
# 转换为RGB格式
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 显示图像
plt.imshow(img_rgb)
plt.axis('off')
plt.show()
2. 使用 PIL/Pillow 读取图像
PIL 直接以 RGB 格式读取图像,更直观(看个人选择吧,尽量一个包能解决的问题不要用那么多包,以免打包为EXE时过大,建议使用OpenCV)。
python
from PIL import Image
# 读取图像
img = Image.open('image.jpg')
# 显示图像
img.show()
# 转换为NumPy数组
img_array = np.array(img)
二、尺寸调整(Resize)
统一图像尺寸是预处理的核心步骤,常用插值方法:INTER_LINEAR(双线性插值)、INTER_NEAREST(最近邻)、INTER_CUBIC(双三次插值)。
python
# OpenCV调整尺寸
resized_img = cv2.resize(img_rgb, (224, 224), interpolation=cv2.INTER_LINEAR)
# PIL调整尺寸
resized_img_pil = img.resize((224, 224), Image.Resampling.LANCZOS)
三、图像归一化
将像素值缩放到 [0,1] 或 [-1,1],消除亮度差异影响。
python
# 方法1:除以255(缩放到[0,1])
normalized_img = img_rgb / 255.0
# 方法2:Z-score归一化(均值为0,方差为1)
mean = np.mean(img_rgb)
std = np.std(img_rgb)
normalized_img_z = (img_rgb - mean) / std
四、噪声去除
1. 高斯模糊
适用于高斯噪声。
高斯噪声是图像中像素值围绕真实值呈高斯分布的随机扰动,常见于低光照环境或传感器热噪声。OpenCV的cv2.GaussianBlur函数通过高斯核卷积可有效抑制此类噪声。
原理与作用
- 噪声特性:高斯噪声表现为图像整体模糊或颗粒感,像素值分布符合正态分布 。
- 滤波机制:高斯模糊通过高斯核对图像进行加权平均,中心像素权重最大,邻域权重递减,从而平滑噪声 。
参数设置
- 高斯核尺寸(
ksize):奇数大小(如5x5),核越大模糊越强 。 - 标准差(
sigmaX/sigmaY):控制权重分布范围,值越大模糊越明显 。若设为0,OpenCV自动计算 。
python
blur_gaussian = cv2.GaussianBlur(img_rgb, (5, 5), 0) # (5,5)为卷积核大小
2. 中值滤波
适用于椒盐噪声。
中值滤波器(CV2.medianBlur)是OpenCV中用于去除椒盐噪声的非线性滤波方法,通过滑动窗口内像素值的中位数替换中心像素值,有效保留图像边缘信息。
核心原理
- 滑动窗口:通常为3×3或5×5的正方形区域,窗口内像素值排序后取中位数。
- 噪声处理:椒盐噪声表现为孤立的黑白点,中值滤波通过中位数替换可忽略极端值,避免模糊边缘。
参数调整
- 窗口大小:噪声密集时可增大窗口(如5×5),但会略微模糊细节。
python
median_blur = cv2.medianBlur(img_rgb, 5)
3. 双边滤波
保留边缘的同时去噪。
python
bilateral_blur = cv2.bilateralFilter(img_rgb, 9, 75, 75)
OpenCV的双边滤波函数cv2.bilateralFilter用于在平滑图像的同时保留边缘细节,常用于图像去噪和磨皮处理。
函数原型:
python
cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, borderType=BORDER_DEFAULT)
- src: 输入图像(Mat类型)
- d: 邻域直径(非正数时由sigmaSpace计算)
- sigmaColor: 颜色空间标准差(控制颜色混合范围)
- sigmaSpace: 坐标空间标准差(控制空间混合范围)
- borderType: 边界处理模式(默认为BORDER_DEFAULT)
关键参数说明
- d:建议值:实时应用取d=5,离线处理取d=9 。
- sigmaColor与sigmaSpace:值越小,保留细节越多;值越大,平滑效果越强 。
- 效果对比:保留边缘优于高斯滤波,但计算成本较高 。
五、图像增强
1. 直方图均衡化(增强对比度)
适用于灰度图像,彩色图像需分通道处理。
python
# 灰度图像直方图均衡化
gray_img = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
equalized_gray = cv2.equalizeHist(gray_img)
# 彩色图像直方图均衡化(YUV空间)
img_yuv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2YUV)
img_yuv[:, :, 0] = cv2.equalizeHist(img_yuv[:, :, 0])
equalized_color = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2RGB)
基本原理
- 核心思想:将图像灰度值的分布拉伸至全范围(0-255),使暗部和亮部细节更清晰。
- 数学方法:基于累计分布函数(CDF),将原灰度值映射到新值:
新灰度值 = CDF(原灰度值) × 255。
注意事项
- 仅适用于单通道图像(灰度或亮度通道),多通道彩色需预处理。
- 可能导致过曝或细节丢失,需结合CLAHE等改进方法。
2. 亮度与对比度调整
python
# alpha:对比度(1.0-3.0),beta:亮度(0-100)
adjusted = cv2.convertScaleAbs(img_rgb, alpha=1.5, beta=30)
六、图像格式转换
1. 彩色转灰度
python
gray_img = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
2. 图像转数组 / 张量
python
import numpy as np
import torch
# PIL图像转NumPy数组
img_array = np.array(img)
# NumPy数组转PyTorch张量
tensor_img = torch.from_numpy(img_array).permute(2, 0, 1).float() # 通道优先
七、数据增强(Data Augmentation)
常用库:torchvision.transforms、albumentations。
python
from torchvision import transforms
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(p=0.5), # 随机水平翻转
transforms.RandomRotation(15), # 随机旋转
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # 标准化
])
# 应用变换
augmented_img = transform(img)
八、总结
图像预处理的核心目标是:统一数据格式、消除干扰信息、增强有用特征,为后续模型训练或分析奠定基础。根据任务(分类、检测、分割等)选择合适的预处理步骤,例如:
- 分类任务:重点关注尺寸统一、归一化、数据增强;
- 检测任务:需保留坐标信息,避免破坏性变换;
- 医学图像:常需去噪、对比度增强等。
结合 OpenCV、PIL、PyTorch 等工具可高效完成预处理流程,可根据需求灵活组合方法。