【OpenCV 入门到精通 03】图像入门:读取、显示、保存完全指南
标签 :
OpenCVimreadimshowimwrite图像读写Mat难度 :⭐ 入门 | 阅读时长 :约 50 分钟 | 系列 :第 03/12 集

写在前面
图像处理的第一步:把图片读进内存、显示出来、保存出去 。对应官方文档 2_1 图像入门。
本集覆盖 imread / imshow / imwrite 三大核心函数,以及像素访问、图像属性等基础操作。
本集学习目标
- 熟练使用 imread / imshow / imwrite
- 理解图像属性(shape、dtype、size)
- 掌握像素级访问与修改
- 处理中文路径和多种图像格式
目录
- [3.1 读取图像 imread](#3.1 读取图像 imread)
- [3.2 显示图像 imshow](#3.2 显示图像 imshow)
- [3.3 保存图像 imwrite](#3.3 保存图像 imwrite)
- [3.4 图像属性](#3.4 图像属性)
- [3.5 像素访问](#3.5 像素访问)
- [3.6 踩坑指南](#3.6 踩坑指南)
- [3.7 FAQ](#3.7 FAQ)
- [3.8 本集小结](#3.8 本集小结)
3.1 读取图像 imread
python
import cv2
img = cv2.imread("photo.jpg") # 默认彩色 BGR
gray = cv2.imread("photo.jpg", 0) # 灰度
gray = cv2.imread("photo.jpg", cv2.IMREAD_GRAYSCALE)
rgba = cv2.imread("photo.png", cv2.IMREAD_UNCHANGED) # 含 Alpha
imread 标志位
| 标志 | 值 | 说明 |
|---|---|---|
IMREAD_COLOR |
1 | 彩色 BGR(默认) |
IMREAD_GRAYSCALE |
0 | 灰度单通道 |
IMREAD_UNCHANGED |
-1 | 含 Alpha 通道 |
检查是否读取成功
python
img = cv2.imread("photo.jpg")
if img is None:
print("读取失败!检查:1.路径 2.格式 3.中文路径")
else:
print(f"成功: {img.shape}")
3.2 显示图像 imshow
python
cv2.imshow("窗口标题", img)
key = cv2.waitKey(0) # 0=无限等待;30=等待30ms
cv2.destroyAllWindows()
# 按 q 退出
while True:
cv2.imshow("img", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
| 函数 | 说明 |
|---|---|
imshow(name, mat) |
创建/更新窗口 |
waitKey(delay) |
等待按键,返回键值 |
destroyAllWindows() |
关闭所有窗口 |
namedWindow(name, flags) |
创建可调整大小的窗口 |
python
cv2.namedWindow("img", cv2.WINDOW_NORMAL) # 可拖拽缩放
cv2.imshow("img", img)
3.3 保存图像 imwrite
python
cv2.imwrite("output.jpg", img) # JPEG
cv2.imwrite("output.png", img) # PNG(无损)
cv2.imwrite("output.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 95])
支持格式
| 格式 | 扩展名 | 特点 |
|---|---|---|
| JPEG | .jpg .jpeg | 有损压缩,体积小 |
| PNG | .png | 无损,支持透明 |
| BMP | .bmp | 无压缩,体积大 |
| TIFF | .tiff | 科研常用 |
| WebP | .webp | 新格式,高压缩比 |
3.4 图像属性
python
img = cv2.imread("photo.jpg")
print(img.shape) # (高, 宽, 通道) 如 (480, 640, 3)
print(img.dtype) # uint8
print(img.size) # 总像素数 = H*W*C
print(img.ndim) # 维度数:灰度2,彩色3
h, w = img.shape[:2]
print(f"宽={w}, 高={h}")
| 属性 | 灰度图 | 彩色图 |
|---|---|---|
| shape | (H, W) | (H, W, 3) |
| dtype | uint8 | uint8 |
| 单像素大小 | 1 字节 | 3 字节 |
3.5 像素访问与修改
访问单个像素
python
# 彩色:返回 [B, G, R]
px = img[100, 200]
b, g, r = img[100, 200]
print(f"B={b}, G={g}, R={r}")
# 灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
val = gray[100, 200]
修改像素
python
# 画一个红色方块 (BGR: 0,0,255)
img[50:100, 50:100] = [0, 0, 255]
推荐:numpy 切片操作区域
python
roi = img[100:200, 150:250] # 区域 of interest
roi[:] = (0, 255, 0) # 整个区域变绿
3.6 踩坑指南
| 坑 | 解决 |
|---|---|
| imread 返回 None | 检查路径;中文路径用 imdecode |
| 颜色不对(偏蓝/偏红) | OpenCV 是 BGR,显示前转 RGB |
| imshow 闪退 | 必须配合 waitKey |
| JPEG 保存质量差 | 设置 IMWRITE_JPEG_QUALITY |
| shape 宽高搞反 | shape 是 (高, 宽),不是 (宽, 高) |
BGR → RGB 显示
python
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("photo.jpg")
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(rgb)
plt.show()
3.7 常见问题 FAQ
Q1:一张 4K 图占多少内存?
A:3840×2160×3 ≈ 24 MB(uint8)
Q2:能直接修改 imread 返回的数组吗?
A:能,OpenCV 图像就是 NumPy 数组,原地修改。
3.8 本集小结
| 操作 | 函数 |
|---|---|
| 读取 | cv2.imread(path, flags) |
| 显示 | cv2.imshow() + cv2.waitKey() |
| 保存 | cv2.imwrite(path, img) |
| 属性 | .shape .dtype .size |
| 像素 | img[y, x] 或 img[y1:y2, x1:x2] |
| ← 第02集 | 第04集:视频与绘图 → |
|---|
参考:2_1 图像入门