人工智能之视觉领域 计算机视觉
第四章 图像基本操作
文章目录
- [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
- [前言:图像的基本操作 ------ 读取、显示、保存与变换](#前言:图像的基本操作 —— 读取、显示、保存与变换)
- [4.1 图像的读取、显示与保存](#4.1 图像的读取、显示与保存)
- [📌 核心三函数](#📌 核心三函数)
- [✅ 完整示例:读取 → 显示 → 保存](#✅ 完整示例:读取 → 显示 → 保存)
- [🔁 BGR vs RGB:为什么颜色看起来怪怪的?](#🔁 BGR vs RGB:为什么颜色看起来怪怪的?)
- [4.2 图像的基本属性查看](#4.2 图像的基本属性查看)
- [📊 三大核心属性](#📊 三大核心属性)
- [💡 代码示例:自动判断图像类型](#💡 代码示例:自动判断图像类型)
- [4.3 图像的裁剪、缩放与翻转](#4.3 图像的裁剪、缩放与翻转)
- [✂️ 1. 裁剪(ROI:Region of Interest)](#✂️ 1. 裁剪(ROI:Region of Interest))
- [🔍 2. 缩放(Resize)](#🔍 2. 缩放(Resize))
- [🔄 3. 翻转(Flip)](#🔄 3. 翻转(Flip))
- [4.4 图像算术运算(加减乘除)](#4.4 图像算术运算(加减乘除))
- [⚠️ 重要前提:像素值范围 [0, 255](uint8)](#⚠️ 重要前提:像素值范围 [0, 255](uint8))
- [➕ 加法:调整亮度](#➕ 加法:调整亮度)
- [➖ 减法:提取差异(背景消除)](#➖ 减法:提取差异(背景消除))
- [✖️ 乘法 / 除法:调整对比度](#✖️ 乘法 / 除法:调整对比度)
- [🧩 综合实战:图像处理流水线](#🧩 综合实战:图像处理流水线)
- [🧪 完整代码实现](#🧪 完整代码实现)
- [🚫 常见错误与解决方案](#🚫 常见错误与解决方案)
- [✅ 本章小结](#✅ 本章小结)
- 资料关注
前言:图像的基本操作 ------ 读取、显示、保存与变换
学习目标总览:
- 能独立完成图像的 读取 → 显示 → 保存 全流程
- 能快速判断图像是 灰度还是彩色
- 能对图像进行 裁剪、缩放、翻转
- 能用 算术运算 调整亮度/对比度,理解像素级操作规则
4.1 图像的读取、显示与保存
📌 核心三函数
| 函数 | 作用 | 常见参数 |
|---|---|---|
cv2.imread(path, flags) |
从磁盘读取图像 | flags=cv2.IMREAD_COLOR(默认,BGR)cv2.IMREAD_GRAYSCALE(灰度) |
cv2.imshow(winname, img) |
在窗口中显示图像 | winname:窗口标题img:NumPy 数组 |
cv2.imwrite(path, img) |
将图像保存到磁盘 | 自动根据扩展名决定格式(.jpg/.png等) |
✅ 完整示例:读取 → 显示 → 保存
python
import cv2
# 1. 读取图像(注意:路径不能含中文!)
img = cv2.imread('photo.jpg') # 默认彩色(BGR)
# 检查是否读取成功
if img is None:
print("❌ 图像未找到!请检查文件路径和名称(避免中文路径)")
else:
print("✅ 图像读取成功!")
# 2. 显示图像
cv2.imshow('Original Image', img)
cv2.waitKey(0) # 等待任意键按下
cv2.destroyAllWindows() # 关闭所有窗口
# 3. 保存为新文件
cv2.imwrite('output_photo.jpg', img)
print("✅ 图像已保存为 output_photo.jpg")
⚠️ 新手避坑指南:
- 路径不能有中文 :Windows 用户常犯错误!建议将图片放在英文路径下,如
C:/images/photo.jpg- 文件扩展名要正确 :
.jpg、.png、.bmp等- Jupyter / 服务器环境无法使用
cv2.imshow()→ 改用matplotlib(见后文)
🔁 BGR vs RGB:为什么颜色看起来怪怪的?
OpenCV 使用 BGR 顺序 ,但 matplotlib / PIL / 浏览器使用 RGB。
python
import cv2
import matplotlib.pyplot as plt
img_bgr = cv2.imread('photo.jpg')
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) # 转换为 RGB
# 对比显示
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.title("BGR (OpenCV 默认)")
plt.imshow(img_bgr) # 颜色错乱!
plt.axis('off')
plt.subplot(1, 2, 2)
plt.title("RGB (正确显示)")
plt.imshow(img_rgb)
plt.axis('off')
plt.show()
✅ 结论:
- 用 OpenCV 处理 → 保持 BGR
- 用 matplotlib 显示 → 转为 RGB
4.2 图像的基本属性查看
📊 三大核心属性
| 属性 | 含义 | 示例值(彩色图) | 示例值(灰度图) |
|---|---|---|---|
img.shape |
形状(高, 宽, 通道数) | (480, 640, 3) |
(480, 640) |
img.size |
像素总数(H×W×C) | 921600 |
307200 |
img.dtype |
数据类型 | uint8 |
uint8 |
💡 代码示例:自动判断图像类型
python
import cv2
def inspect_image(path):
img = cv2.imread(path)
if img is None:
print("❌ 无法读取图像")
return
h, w = img.shape[:2]
channels = img.shape[2] if len(img.shape) == 3 else 1
img_type = "彩色" if channels == 3 else "灰度"
print(f"📄 文件: {path}")
print(f"📏 尺寸: {w} × {h}")
print(f"🎨 类型: {img_type} ({channels} 通道)")
print(f"🔢 数据类型: {img.dtype}")
print(f"🧮 像素总数: {img.size}")
# 使用
inspect_image('photo.jpg')
输出示例:
📄 文件: photo.jpg
📏 尺寸: 640 × 480
🎨 类型: 彩色 (3 通道)
🔢 数据类型: uint8
🧮 像素总数: 921600
4.3 图像的裁剪、缩放与翻转
✂️ 1. 裁剪(ROI:Region of Interest)
利用 NumPy 切片:img[y1:y2, x1:x2]
python
# 裁剪中间 200x200 区域
cropped = img[100:300, 200:400]
cv2.imshow('Cropped', cropped)
cv2.waitKey(0)
cv2.destroyAllWindows()
🎯 应用场景:人脸检测后只保留人脸区域
🔍 2. 缩放(Resize)
python
# 方法1:指定绝对尺寸
resized1 = cv2.resize(img, (320, 240)) # (宽, 高)
# 方法2:按比例缩放(推荐保持宽高比)
scale = 0.5
width = int(img.shape[1] * scale)
height = int(img.shape[0] * scale)
resized2 = cv2.resize(img, (width, height))
# 方法3:使用插值算法(高质量缩放)
resized3 = cv2.resize(img, (0,0), fx=0.5, fy=0.5,
interpolation=cv2.INTER_CUBIC)
📌 插值方法选择:
INTER_NEAREST:最快,质量低(像素化)INTER_LINEAR:默认,平衡速度与质量INTER_CUBIC:慢,高质量(适合放大)
🔄 3. 翻转(Flip)
python
# 水平翻转(镜像)
flip_h = cv2.flip(img, 1)
# 垂直翻转
flip_v = cv2.flip(img, 0)
# 同时水平+垂直翻转(旋转180°)
flip_both = cv2.flip(img, -1)
# 显示对比
cv2.imshow('Original', img)
cv2.imshow('Horizontal Flip', flip_h)
cv2.imshow('Vertical Flip', flip_v)
cv2.waitKey(0)
cv2.destroyAllWindows()
参数说明:
flipCode = 1:水平翻转(绕 y 轴)flipCode = 0:垂直翻转(绕 x 轴)flipCode = -1:两者都翻转
4.4 图像算术运算(加减乘除)
⚠️ 重要前提:像素值范围 [0, 255](uint8)
直接用 NumPy 运算会 溢出 (255 + 10 = 9),而 OpenCV 提供 饱和运算:
| 操作 | NumPy (+) |
OpenCV (cv2.add) |
|---|---|---|
| 200 + 100 | 44(溢出) | 255(饱和) |
| 50 - 100 | 206(负数变正) | 0(截断) |
➕ 加法:调整亮度
python
# 方法1:使用 cv2.add(安全)
brighter = cv2.add(img, 50) # 所有像素 +50,上限255
# 方法2:自定义(需手动处理溢出)
brighter2 = np.clip(img.astype(np.int16) + 50, 0, 255).astype(np.uint8)
➖ 减法:提取差异(背景消除)
python
# 假设有背景图 background 和当前帧 frame
diff = cv2.absdiff(frame, background) # 绝对差值
# 或
diff = cv2.subtract(frame, background) # 单向差值
🎥 应用:视频监控中检测运动物体
✖️ 乘法 / 除法:调整对比度
python
# 对比度增强:new_pixel = alpha * pixel + beta
alpha = 1.5 # 对比度增益 (>1 增强)
beta = 0 # 亮度偏移
contrast_img = cv2.convertScaleAbs(img, alpha=alpha, beta=beta)
# 等价于:
# contrast_img = np.clip(alpha * img + beta, 0, 255).astype(np.uint8)
📌
cv2.convertScaleAbs():自动处理浮点 → uint8 转换
🧩 综合实战:图像处理流水线
否
是
读取图像 imread
是否有效?
报错退出
查看属性 shape/dtype
裁剪 ROI
缩放 resize
水平翻转 flip
增加亮度 add
保存结果 imwrite
显示结果 imshow
🧪 完整代码实现
python
import cv2
import numpy as np
# 1. 读取
img = cv2.imread('input.jpg')
if img is None:
raise FileNotFoundError("请提供有效的图像路径(避免中文)")
# 2. 查看属性
print(f"原始尺寸: {img.shape[1]}x{img.shape[0]}")
# 3. 裁剪中心区域
h, w = img.shape[:2]
crop_size = min(h, w) // 2
start_y = (h - crop_size) // 2
start_x = (w - crop_size) // 2
cropped = img[start_y:start_y+crop_size, start_x:start_x+crop_size]
# 4. 缩放至 300x300
resized = cv2.resize(cropped, (300, 300))
# 5. 水平翻转
flipped = cv2.flip(resized, 1)
# 6. 提升亮度和对比度
enhanced = cv2.convertScaleAbs(flipped, alpha=1.3, beta=20)
# 7. 保存
cv2.imwrite('processed_output.jpg', enhanced)
# 8. 显示
cv2.imshow('Processed Image', enhanced)
cv2.waitKey(0)
cv2.destroyAllWindows()
print("✅ 处理完成!结果已保存为 processed_output.jpg")
🚫 常见错误与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
cv2.imshow() 无反应 |
在 Jupyter / 服务器运行 | 改用 matplotlib 显示 |
| 图像全黑/全白 | 数据类型不是 uint8 |
用 .astype(np.uint8) 转换 |
| 中文路径报错 | OpenCV 不支持 Unicode 路径 | 使用英文路径,或改用 cv2.imdecode(np.fromfile(...))(高级) |
| 保存后图像失真 | 保存为 .jpg 且压缩过高 | 改用 .png,或指定 JPEG 质量:cv2.imwrite('a.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 95]) |
✅ 本章小结
| 操作 | 核心函数/方法 | 关键点 |
|---|---|---|
| 读取 | cv2.imread() |
避免中文路径,注意 BGR |
| 显示 | cv2.imshow() |
GUI 环境可用,否则用 matplotlib |
| 保存 | cv2.imwrite() |
自动识别格式 |
| 属性 | .shape, .dtype |
判断灰度/彩色 |
| 裁剪 | img[y1:y2, x1:x2] |
NumPy 切片 |
| 缩放 | cv2.resize() |
注意插值方法 |
| 翻转 | cv2.flip() |
1=水平,0=垂直,-1=两者 |
| 算术 | cv2.add(), convertScaleAbs() |
防止溢出,用饱和运算 |
🌟 可以:
- 读一张图,裁掉不需要的部分
- 把它缩小发朋友圈
- 加点亮度让它更"通透"
- 保存下来分享给朋友!
资料关注
公众号:咚咚王
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》