人工智能之视觉领域 计算机视觉
第三章 NumPy 与图像矩阵
文章目录
- [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
- [前言:OpenCV 核心数据结构 ------ NumPy 与图像矩阵](#前言:OpenCV 核心数据结构 —— NumPy 与图像矩阵)
- [1. 通俗理解:图像是什么?](#1. 通俗理解:图像是什么?)
- [🖼️ 图像类型与矩阵形状对应关系:](#🖼️ 图像类型与矩阵形状对应关系:)
- [2. 为什么 OpenCV 依赖 NumPy?](#2. 为什么 OpenCV 依赖 NumPy?)
- [3. 图像 ↔ 矩阵:直观对应示例](#3. 图像 ↔ 矩阵:直观对应示例)
- [示例 1:创建一个 3×3 的灰度小图](#示例 1:创建一个 3×3 的灰度小图)
- [示例 2:彩色图像的三维结构](#示例 2:彩色图像的三维结构)
- [4. 核心 NumPy 操作(OpenCV 必备)](#4. 核心 NumPy 操作(OpenCV 必备))
- [4.1 查看图像基本信息](#4.1 查看图像基本信息)
- [4.2 访问与修改像素](#4.2 访问与修改像素)
- [4.3 通道分离与合并](#4.3 通道分离与合并)
- [4.4 图像 ROI(感兴趣区域)](#4.4 图像 ROI(感兴趣区域))
- [5. 数据类型与取值范围](#5. 数据类型与取值范围)
- [6. 图像矩阵操作流程图(Mermaid)](#6. 图像矩阵操作流程图(Mermaid))
- [7. 配套代码实战:图像矩阵探索工具](#7. 配套代码实战:图像矩阵探索工具)
- [8. 常见误区提醒](#8. 常见误区提醒)
- 总结
- 资料关注
前言:OpenCV 核心数据结构 ------ NumPy 与图像矩阵
学习目标:理解"图像 = 数字矩阵"的本质,掌握 OpenCV 与 NumPy 的协同工作机制,能对图像进行基础的矩阵操作。
1. 通俗理解:图像是什么?
想象一张 1920×1080 的彩色照片 。
在人眼中,它是风景、人脸或猫咪;
但在计算机眼里,它只是一堆 数字!
✅ 核心观点 :
图像是一个由像素(Pixel)组成的矩阵,每个像素用数字表示颜色。
🖼️ 图像类型与矩阵形状对应关系:
| 图像类型 | 矩阵维度(Shape) | 说明 |
|---|---|---|
| 灰度图 | (H, W) |
高 × 宽,每个值 ∈ [0, 255](0=黑,255=白) |
| 彩色图(BGR) | (H, W, 3) |
3 个通道:Blue, Green, Red(注意顺序!) |
| 带透明通道(BGRA) | (H, W, 4) |
多一个 Alpha 通道(透明度) |
🔍 示例:一张 480×640 的彩色图 →
img.shape = (480, 640, 3)
2. 为什么 OpenCV 依赖 NumPy?
OpenCV 的 Python 接口 完全基于 NumPy 数组(ndarray) 。
这意味着:
- 你用
cv2.imread()读进来的图像,本质上是一个 NumPy 数组 - 所有图像操作(裁剪、旋转、滤波)都是 对 NumPy 数组的操作
- 你可以无缝使用 NumPy 的强大功能(切片、广播、数学运算)
💡 一句话总结 :
OpenCV 负责"视觉算法",NumPy 负责"数据存储与计算"。
3. 图像 ↔ 矩阵:直观对应示例
示例 1:创建一个 3×3 的灰度小图
python
import numpy as np
# 创建一个 3x3 的灰度图像(数值代表亮度)
gray_img = np.array([
[0, 128, 255],
[64, 192, 32 ],
[255, 0, 128]
], dtype=np.uint8)
print("图像矩阵:")
print(gray_img)
print("形状:", gray_img.shape) # (3, 3)
输出:
图像矩阵:
[[ 0 128 255]
[ 64 192 32]
[255 0 128]]
形状: (3, 3)
🎨 可视化理解:
- 左上角是黑色(0)
- 右上角是白色(255)
- 中间是灰色(128~192)
示例 2:彩色图像的三维结构
python
import cv2
import numpy as np
# 创建一个 2x2 的纯红色小图(BGR格式!)
red_img = np.zeros((2, 2, 3), dtype=np.uint8)
red_img[:, :, 2] = 255 # R 通道设为 255
print("红色图像矩阵:")
print(red_img)
print("形状:", red_img.shape) # (2, 2, 3)
输出:
红色图像矩阵:
[[[ 0 0 255]
[ 0 0 255]]
[[ 0 0 255]
[ 0 0 255]]]
形状: (2, 2, 3)
⚠️ 注意:OpenCV 使用 BGR 顺序 ,不是 RGB!
所以
[0, 0, 255]表示 红色(Blue=0, Green=0, Red=255)
4. 核心 NumPy 操作(OpenCV 必备)
4.1 查看图像基本信息
python
import cv2
img = cv2.imread('photo.jpg')
print("数据类型:", img.dtype) # uint8(0~255)
print("形状:", img.shape) # (高, 宽, 通道数)
print("像素总数:", img.size) # 高 × 宽 × 通道
print("维度数:", img.ndim) # 3(彩色图)
4.2 访问与修改像素
python
# 获取 (y, x) 处的像素值(注意:先 y 后 x!)
pixel = img[100, 200] # 第100行、第200列的像素
# 修改为白色(BGR)
img[100, 200] = [255, 255, 255]
# 修改整个区域(切片)
img[50:100, 100:200] = [0, 255, 0] # 绿色方块
📌 坐标系统:
img[y, x]→ y 是行(高度方向),x 是列(宽度方向)- 原点 (0,0) 在 左上角
4.3 通道分离与合并
python
# 分离 B, G, R 通道
b, g, r = cv2.split(img)
# 或用 NumPy 切片(更快!)
b = img[:, :, 0]
g = img[:, :, 1]
r = img[:, :, 2]
# 合并通道
img_merged = cv2.merge([b, g, r])
# 创建只有红色的图像
red_only = np.zeros_like(img)
red_only[:, :, 2] = r # 保留 R 通道,其他为 0
4.4 图像 ROI(感兴趣区域)
python
# 裁剪图像的一部分(ROI)
roi = img[100:300, 200:400] # 高从100到300,宽从200到400
# 将 ROI 复制到另一个位置
img[0:200, 0:200] = roi
✅ 这就是"贴图"、"打码"、"局部处理"的基础!
5. 数据类型与取值范围
| 数据类型 | 取值范围 | 用途 |
|---|---|---|
uint8 |
0 ~ 255 | 标准图像格式(8位) |
float32 |
0.0 ~ 1.0 或 -1.0 ~ 1.0 | 深度学习、浮点运算 |
int16 |
-32768 ~ 32767 | 特定传感器数据 |
⚠️ 重要规则:
- 显示或保存图像时,必须是
uint8(0~255)- 若计算结果超出范围(如负数或 >255),会自动截断或报错!
python
# 错误示例:直接相加可能溢出
img1 = cv2.imread('a.jpg')
img2 = cv2.imread('b.jpg')
result = img1 + img2 # 若某像素和为 300 → 自动变为 44(300 % 256)
# 正确做法:使用 cv2.add()(饱和运算)
result = cv2.add(img1, img2) # 300 → 255(不会溢出)
6. 图像矩阵操作流程图(Mermaid)
彩色
灰度
读取图像 cv2.imread
图像类型?
矩阵 shape = H,W,3
矩阵 shape = H,W
NumPy 数组 uint8
可执行: 切片/运算/通道操作
显示 cv2.imshow 或保存 cv2.imwrite
7. 配套代码实战:图像矩阵探索工具
python
import cv2
import numpy as np
def explore_image(image_path):
"""深入探索一张图像的矩阵结构"""
img = cv2.imread(image_path)
if img is None:
print("❌ 图像未找到,请检查路径")
return
print("="*50)
print(f"🔍 图像分析: {image_path}")
print(f"形状 (H, W, C): {img.shape}")
print(f"数据类型: {img.dtype}")
print(f"最小值: {img.min()}, 最大值: {img.max()}")
# 显示中心像素
h, w = img.shape[:2]
center_pixel = img[h//2, w//2]
print(f"中心像素 (B,G,R): {center_pixel}")
# 创建通道分离图
b, g, r = cv2.split(img)
zeros = np.zeros_like(b)
blue_img = cv2.merge([b, zeros, zeros])
green_img = cv2.merge([zeros, g, zeros])
red_img = cv2.merge([zeros, zeros, r])
# 显示(或保存)
cv2.imshow('Original', img)
cv2.imshow('Blue Channel', blue_img)
cv2.imshow('Green Channel', green_img)
cv2.imshow('Red Channel', red_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 使用示例
# explore_image('your_photo.jpg')
8. 常见误区提醒
| 误区 | 正确认知 |
|---|---|
| "图像是 RGB" | OpenCV 默认是 BGR !显示前需转 RGB(用 cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) |
| "img[x, y] 是第 x 列 y 行" | 实际是 img[y, x]!先行后列(NumPy 索引规则) |
| "可以直接用 + - * / 运算" | 小心溢出!推荐用 cv2.add(), cv2.subtract() 等安全函数 |
| "float 图像可以直接显示" | cv2.imshow() 要求 uint8,浮点图需乘以 255 并转类型 |
总结
图像的本质是矩阵,OpenCV 的灵魂是 NumPy 。
掌握以下三点,你就迈出了计算机视觉的关键一步:
- ✅ 图像 =
np.ndarray,形状为(H, W)或(H, W, 3) - ✅ 像素访问:
img[y, x],通道:img[:, :, 0](B) - ✅ 所有操作都是对数组的数学/逻辑运算
🚀 下一步:我们将学习如何对这些矩阵进行"美容"------图像预处理(灰度化、滤波、边缘检测)!
📚 练习:
- 用 NumPy 创建一个渐变色图像(从黑到白)
- 将一张彩色图转换为"只有蓝色"的图像
- 计算图像的平均亮度(对灰度图求均值)
资料关注
公众号:咚咚王
gitee:https://gitee.com/wy18585051844/ai_learning
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》