SciPy - Ndimage
SciPy - 多维图像处理(scipy.ndimage)
Section titled “SciPy - 多维图像处理(scipy.ndimage)”scipy.ndimage 模块专注于 N 维图像处理。它提供了广泛的功能,用于对 NumPy 数组进行滤波、插值、测量、形态学操作以及其他常见的图像处理任务。
使用 scipy.ndimage 可以完成的常见图像处理任务包括:
- 读写图像(通常借助 Matplotlib 或 ImageIO 等其他库)。
- 基本操作:裁剪、翻转、旋转。
- 图像滤波:去噪、锐化、模糊(例如,高斯滤波)。
- 形态学操作:腐蚀、膨胀、开运算、闭运算。
- 对象测量:查找质心、标记特征。
- 插值和几何变换。
对于更高级的图像分析(例如,SIFT/SURF 等特征检测、复杂分割算法),通常会结合使用或替代 scipy.ndimage 使用 scikit-image、OpenCV 或 Mahotas 等库。
加载和显示图像
Section titled “加载和显示图像”SciPy 本身不侧重于图像输入/输出 (I/O)。scipy.datasets.face() 提供了一个示例彩色图像(一只浣熊),以 NumPy 数组形式呈现。对于通用图像加载,推荐使用 matplotlib.image 或 imageio 等库。
from scipy import datasets # For the sample imageimport matplotlib.pyplot as pltimport numpy as np
# Load the sample 'face' image (a racoon)# It's a 3D NumPy array (height, width, color_channels)# 加载示例 'face' 图像(一只浣熊)# 这是一个 3D 的 NumPy 数组(高、宽、颜色通道)face_color = datasets.face()
# Load a grayscale version if available, or convert# face_gray = datasets.face(gray=True) # This was an option in older scipy.misc# For current datasets.face(), convert manually if needed:# 如果可用,加载灰度版本,或进行转换# face_gray = datasets.face(gray=True) # 这是旧版本 scipy.misc 中的一个选项# 对于当前的 datasets.face(),如果需要,请手动转换:face_gray = np.mean(face_color, axis=2).astype(np.uint8)
# Display the image using Matplotlib# 使用 Matplotlib 显示图像fig, axes = plt.subplots(1, 2, figsize=(10, 5))axes[0].imshow(face_color)axes[0].set_title('Color Face Image')axes[0].axis('off')
axes[1].imshow(face_gray, cmap='gray')axes[1].set_title('Grayscale Face Image')axes[1].axis('off')
plt.tight_layout()# plt.show()# Description: This code loads a sample image of a racoon, once in color and# once converted to grayscale. It then displays both side-by-side using Matplotlib.# 描述:此代码加载一只浣熊的示例图像,一次是彩色的,一次是转换为灰度的。# 然后使用 Matplotlib 将两者并排显示。图像在其原始数字形式中本质上是一个 NumPy 数组,其中像素值表示强度或颜色。对于灰度图像,它通常是一个 2D 数组。对于彩色图像(例如,RGB),它是一个 3D 数组(高、宽、3 个通道)。
基本图像统计信息:
from scipy import datasetsimport numpy as np
face = datasets.face() # Color image# face = datasets.face() # 彩色图像print(f"Image shape: {face.shape}") # 图像形状print(f"Data type: {face.dtype}") # 数据类型print(f"Mean pixel value (overall): {face.mean():.2f}") # 平均像素值(整体)print(f"Max pixel value: {face.max()}") # 最大像素值print(f"Min pixel value: {face.min()}") # 最小像素值输出(根据 SciPy 版本/数据集的具体情况会略有差异):
Image shape: (768, 1024, 3)Data type: uint8Mean pixel value (overall): 114.51Max pixel value: 255Min pixel value: 0由于图像是 NumPy 数组,因此可以使用数组切片进行基本的变换,例如裁剪。scipy.ndimage 提供了用于更复杂变换的功能,例如旋转和缩放。
from scipy import datasetsimport matplotlib.pyplot as pltimport numpy as np
face_gray = np.mean(datasets.face(), axis=2).astype(np.uint8)height, width = face_gray.shape
# Crop the central part of the image# Remove 1/4th from each side (top, bottom, left, right)# 裁剪图像的中心部分# 从每一侧(上、下、左、右)各移除 1/4crop_start_h, crop_end_h = height // 4, height - height // 4crop_start_w, crop_end_w = width // 4, width - width // 4cropped_face = face_gray[crop_start_h:crop_end_h, crop_start_w:crop_end_w]
plt.figure(figsize=(5, 5))plt.imshow(cropped_face, cmap='gray')plt.title('Cropped Grayscale Face') # 裁剪后的灰度图像标题plt.axis('off') # 关闭坐标轴# plt.show()# Description: This code will display the central cropped portion of the grayscale racoon image.# 描述:此代码将显示灰度浣熊图像的中心裁剪部分。NumPy 的 flipud(上下翻转)和 fliplr(左右翻转)非常有用。
from scipy import datasetsimport numpy as npimport matplotlib.pyplot as plt
face_color = datasets.face()
# Flip upside down# 上下翻转flipped_ud_face = np.flipud(face_color)
plt.figure(figsize=(5,5))plt.imshow(flipped_ud_face)plt.title('Up-Down Flipped Face') # 上下翻转图像标题plt.axis('off') # 关闭坐标轴# plt.show()# Description: This code will display the racoon image flipped vertically.# 描述:此代码将垂直翻转并显示浣熊图像。scipy.ndimage.rotate() 函数按指定角度(以度为单位)旋转图像。
from scipy import datasets, ndimageimport matplotlib.pyplot as plt
face_color = datasets.face()
# Rotate the image by 45 degrees. By default, fills outside areas with 0.# 'reshape=False' keeps original image dimensions, cropping rotated parts.# 将图像旋转 45 度。默认情况下,外部区域填充 0。# 'reshape=False' 保留原始图像尺寸,裁剪旋转后的部分。rotated_face = ndimage.rotate(face_color, 45, reshape=False)
plt.figure(figsize=(5,5))plt.imshow(rotated_face)plt.title('Rotated Face (45 degrees)') # 旋转后的图像标题 (45 度)plt.axis('off') # 关闭坐标轴# plt.show()# Description: This code will display the racoon image rotated by 45 degrees clockwise,# with parts of the image outside the original bounds cropped.# 描述:此代码将显示顺时针旋转 45 度的浣熊图像,# 裁剪掉超出原始边界的图像部分。滤波根据像素的邻域修改像素值,用于平滑、锐化和边缘检测等任务。
高斯模糊 / 平滑
Section titled “高斯模糊 / 平滑”高斯滤波器可以平滑图像并减少噪声。scipy.ndimage.gaussian_filter(input, sigma) 应用此操作。sigma 是高斯核的标准差;sigma 越大,模糊越多。
from scipy import datasets, ndimageimport matplotlib.pyplot as pltimport numpy as np
face_gray = np.mean(datasets.face(), axis=2).astype(np.uint8)
# Apply Gaussian filter with sigma = 3# 应用 sigma = 3 的高斯滤波器blurred_face = ndimage.gaussian_filter(face_gray, sigma=3)
# Apply Gaussian filter with sigma = 7 for more blur# 应用 sigma = 7 的高斯滤波器,以获得更多模糊more_blurred_face = ndimage.gaussian_filter(face_gray, sigma=7)
fig, axes = plt.subplots(1, 3, figsize=(15, 5))axes[0].imshow(face_gray, cmap='gray')axes[0].set_title('Original Grayscale') # 原始灰度图像标题axes[0].axis('off') # 关闭坐标轴
axes[1].imshow(blurred_face, cmap='gray')axes[1].set_title('Blurred (sigma=3)') # 模糊 (sigma=3) 图像标题axes[1].axis('off') # 关闭坐标轴
axes[2].imshow(more_blurred_face, cmap='gray')axes[2].set_title('More Blurred (sigma=7)') # 更模糊 (sigma=7) 图像标题axes[2].axis('off') # 关闭坐标轴
plt.tight_layout()# plt.show()# Description: This code displays the original grayscale image alongside two versions# blurred with a Gaussian filter using different sigma values (3 and 7).# The image with sigma=7 will appear more blurred.# 描述:此代码显示原始灰度图像以及使用不同 sigma 值(3 和 7)# 应用高斯滤波器模糊的两个版本。# sigma=7 的图像将显得更模糊。边缘检测旨在识别亮度的显著变化,这通常对应于对象的边界。
Sobel 滤波器
Section titled “Sobel 滤波器”Sobel 滤波器是一种常见的基于梯度的边缘检测器。scipy.ndimage.sobel(input, axis, output) 沿给定轴计算 Sobel 滤波器。通常将 X 轴和 Y 轴的结果组合起来以获得整体边缘幅度。
from scipy import ndimage, datasetsimport numpy as npimport matplotlib.pyplot as plt
# Create a simple synthetic image for clear edge detection# 创建一个简单的合成图像用于清晰的边缘检测image = np.zeros((128, 128))image[32:-32, 32:-32] = 1 # A white square on a black background # 黑色背景上的白色方块# Add some noise and blur to make it more realistic# 添加一些噪声和模糊使其更逼真image = image + 0.1 * np.random.rand(128,128)image = ndimage.gaussian_filter(image, sigma=2)
# Apply Sobel filter along x-axis (axis=1 for columns/horizontal gradient)# 沿 X 轴应用 Sobel 滤波器(axis=1 表示列/水平梯度)sobel_x = ndimage.sobel(image, axis=1, mode='reflect')
# Apply Sobel filter along y-axis (axis=0 for rows/vertical gradient)# 沿 Y 轴应用 Sobel 滤波器(axis=0 表示行/垂直梯度)sobel_y = ndimage.sobel(image, axis=0, mode='reflect')
# Combine to get edge magnitude# 组合以获得边缘幅度sobel_magnitude = np.hypot(sobel_x, sobel_y)
fig, axes = plt.subplots(1, 4, figsize=(16, 4))axes[0].imshow(image, cmap='gray')axes[0].set_title('Original Synthetic Image') # 原始合成图像标题axes[0].axis('off') # 关闭坐标轴
axes[1].imshow(sobel_x, cmap='gray')axes[1].set_title('Sobel X (Horizontal Edges)') # Sobel X(水平边缘)标题axes[1].axis('off') # 关闭坐标轴
axes[2].imshow(sobel_y, cmap='gray')axes[2].set_title('Sobel Y (Vertical Edges)') # Sobel Y(垂直边缘)标题axes[2].axis('off') # 关闭坐标轴
axes[3].imshow(sobel_magnitude, cmap='gray')axes[3].set_title('Sobel Magnitude (Edges)') # Sobel 幅度(边缘)标题axes[3].axis('off') # 关闭坐标轴
plt.tight_layout()# plt.show()# Description: This code generates a synthetic image of a square, then applies the# Sobel filter to detect its horizontal and vertical edges, and finally shows the# combined edge magnitude. The last image highlights the boundaries of the square.# 描述:此代码生成一个正方形的合成图像,然后应用 Sobel 滤波器# 检测其水平和垂直边缘,最后显示组合的边缘幅度。# 最后一张图像突出显示了正方形的边界。scipy.ndimage 提供了许多其他功能,包括形态学操作(例如,binary_erosion、binary_dilation)、特征测量(center_of_mass、label)和插值(zoom、map_coordinates)。有关详细信息,请查阅官方 SciPy ndimage 文档。