NumPy 中文教程

第一部分:基础认知与环境准备
第 1 章 全面认识 NumPy
第 2 章 开发环境搭建与验证
第二部分:核心对象 ——ndarray 数组
第 3 章 ndarray 数组基础
第 4 章 数组的形状与维度操作
第四部分:高级应用与数据处理
第 8 章 数组的排序、查找与去重
第 9 章 缺失值与异常值处理
第 10 章 随机数生成与抽样
第 11 章 文件读写与数据交互
第五部分:实战场景与落地应用
第 12 章 数值计算实战
第 13 章 数据分析实战
第六部分:优化进阶与问题解决
第 14 章 NumPy 性能优化
第 15 章 NumPy 进阶扩展
第 16 章 常见问题与解决方案

12.3 图像像素处理

NumPy图像处理全面教程:从数组表示到卷积滤波

NumPy 中文教程

本教程作为NumPy高级工程师编写,详细讲解图像处理中的数组表示、像素值调整、图像变换和卷积滤波,代码示例丰富,适合初学者轻松上手学习NumPy图像操作。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

NumPy图像处理教程:从数组表示到卷积滤波

简介

NumPy是Python中用于科学计算的核心库,尤其在图像处理中,它以数组形式高效表示和操作像素数据。本教程将引导你逐步掌握NumPy在图像处理中的应用,从基础概念到实战操作,适合新手学习。

1. 图像的数组表示(高 × 宽 × 通道)

在NumPy中,图像通常被表示为三维数组。对于彩色图像(如RGB),形状为(高度, 宽度, 通道数),其中通道数为3(红、绿、蓝)。灰度图像则是二维数组(高度, 宽度)

示例:加载和表示图像

import numpy as np
import matplotlib.pyplot as plt

# 假设有一个3x3的RGB图像示例
image = np.array([
    [[255, 0, 0], [0, 255, 0], [0, 0, 255]],  # 第一行
    [[128, 128, 128], [64, 64, 64], [192, 192, 192]],  # 第二行
    [[0, 255, 255], [255, 0, 255], [255, 255, 0]]  # 第三行
], dtype=np.uint8)  # 使用uint8类型表示0-255的像素值
print('图像形状:', image.shape)  # 输出: (3, 3, 3)
print('第一个像素值:', image[0, 0, :])  # 输出: [255 0 0]

解释:这创建了一个3x3像素的RGB图像数组,展示了高度、宽度和通道维度。

2. 像素值调整(亮度 / 对比度 / 反转)

调整像素值可以改变图像的外观。NumPy的数组操作使得这些调整简单高效。

2.1 亮度调整

亮度调整通过加减常数来实现,注意像素值范围保持在0-255。

# 增加亮度
bright_image = image + 50  # 每个像素值加50
bright_image = np.clip(bright_image, 0, 255)  # 裁剪到有效范围
print('亮度调整后数组:', bright_image)

2.2 对比度调整

对比度调整使用线性变换:新值 = a * 原值 + b,其中a控制对比度,b控制亮度偏移。

# 增加对比度
a = 1.5  # 对比度因子
b = 0    # 亮度偏移
contrast_image = a * image.astype(float) + b  # 转换为浮点进行计算
contrast_image = np.clip(contrast_image, 0, 255).astype(np.uint8)  # 裁剪并转换回uint8
print('对比度调整后数组:', contrast_image)

2.3 反转

反转图像是将像素值取反,例如从0-255映射到255-0。

# 图像反转
inverted_image = 255 - image
print('反转后数组:', inverted_image)

3. 图像裁剪 / 旋转 / 拼接 / 缩放

这些操作基于NumPy的数组切片和变换功能。

3.1 裁剪

裁剪使用数组切片选择特定区域。

# 裁剪图像的中心区域
cropped_image = image[1:3, 1:3, :]  # 裁剪第二行到第三行,第二列到第三列
print('裁剪后形状:', cropped_image.shape)  # 输出: (2, 2, 3)

3.2 旋转

旋转可以使用NumPy的rot90函数,它顺时针旋转90度。

# 旋转图像90度
rotated_image = np.rot90(image, k=1)  # k=1表示旋转90度
print('旋转后形状:', rotated_image.shape)  # 输出: (3, 3, 3) 保持不变,但内容旋转

更复杂的旋转可能需要插值,但NumPy本身不直接支持;可以使用SciPy等库,但本教程专注于基础NumPy操作。

3.3 拼接

拼接图像使用np.concatenate函数。

# 水平拼接两个图像
image2 = np.zeros_like(image)  # 创建一个相同形状的零数组作为第二个图像
horizontal_concatenated = np.concatenate((image, image2), axis=1)  # 沿宽度轴拼接
print('水平拼接后形状:', horizontal_concatenated.shape)  # 输出: (3, 6, 3)

3.4 缩放

缩放可以通过调整数组大小或重复元素来实现。

# 使用重复缩放(放大)
scaled_image = np.repeat(np.repeat(image, 2, axis=0), 2, axis=1)  # 在每个维度重复2次
print('缩放后形状:', scaled_image.shape)  # 输出: (6, 6, 3)

注意:这种简单缩放可能导致块状效果;实际应用中,可以使用插值方法,但NumPy不直接提供,需结合其他库。

4. 实战:简单图像滤波(卷积操作)

卷积是图像滤波的核心,用于平滑、锐化等效果。我们将实现一个均值滤波作为例子。

4.1 卷积概念

卷积操作使用一个核(kernel)在图像上滑动,计算加权和。均值滤波使用一个3x3的核,所有元素为1/9。

4.2 实现均值滤波

def mean_filter(image):
    # 假设image是二维灰度图像数组
    kernel = np.ones((3, 3)) / 9  # 创建3x3均值核
    filtered_image = np.zeros_like(image, dtype=float)  # 初始化输出数组
    height, width = image.shape
    for i in range(1, height-1):  # 忽略边界
        for j in range(1, width-1):
            # 提取3x3区域并卷积
            region = image[i-1:i+2, j-1:j+2]
            filtered_image[i, j] = np.sum(region * kernel)
    filtered_image = np.clip(filtered_image, 0, 255).astype(np.uint8)  # 裁剪并转换
    return filtered_image

# 示例使用灰度图像
gray_image = np.mean(image, axis=2).astype(np.uint8)  # 将RGB转换为灰度
filtered_gray = mean_filter(gray_image)
print('滤波后灰度图像形状:', filtered_gray.shape)

解释:这个函数实现了基本的均值滤波,通过循环遍历图像并应用核。对于彩色图像,可以对每个通道单独处理。

总结

通过本教程,你学习了如何使用NumPy进行图像处理:从数组表示到像素调整、图像变换和简单卷积滤波。NumPy提供了强大的数组操作,使得图像处理变得高效和直观。继续练习这些技巧,结合实际项目,你将能更深入地掌握图像处理。

提示:在实际应用中,建议结合PIL或OpenCV等库进行更高级的图像操作,但NumPy是这些库的基础。

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包