欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

OpenCV 从零学习 · 第 1 讲:图像的读取、显示与保存(imread / imshow / imwrite)

OpenCV 从零学习 · 第 1 讲:图像的读取、显示与保存

Python OpenCV 从零到精通 · 函数:cv2.imread / cv2.imshow / cv2.imwrite

本讲介绍 OpenCV 处理图像最基础的三个函数:cv2.imread 读取、cv2.imshow 显示、cv2.imwrite 保存,逐一说明它们的参数、返回值与常见注意事项。在 OpenCV 中,所有图像都以 NumPy 数组形式存在,这一点贯穿后续全部内容。


0. 环境准备

pip install opencv-python

import cv2
print(cv2.__version__)   # 例如 4.9.0
包名 opencv-python(核心功能);需要 SIFT/SURF 等扩展模块时用 opencv-contrib-python。注意 PyPI 上的 opencv 是无关废弃包,不要装错。
依赖 numpy 会随包自动安装,图像读写、运算都基于它。

1. cv2.imread — 读取图像

函数签名

cv2.imread(filename, flags=cv2.IMREAD_COLOR) -> ndarray | None
参数 类型 含义
filename str 图像文件路径
flags int 读取模式,决定通道数与色彩,见下表

flags 常用取值

取值 说明
IMREAD_COLOR 1 彩色,3 通道 BGR,忽略透明通道(默认
IMREAD_GRAYSCALE 0 单通道灰度图
IMREAD_UNCHANGED -1 原样读入,保留 alpha 透明通道

返回值:成功返回 ndarray,形状为 (高度, 宽度, 通道数)失败(路径错误、文件损坏)时返回 None,且不抛异常

import cv2

img = cv2.imread("photo.jpg")
if img is None:                      # 必须判空,否则后续对 None 操作会抛 'NoneType' 错误
    raise FileNotFoundError("图片读取失败,检查路径")
print(img.shape)                     # (高度, 宽度, 通道数),例如 (480, 640, 3)
注意
img.shape 的顺序是 (高, 宽, 通道),与日常"宽 × 高"的直觉相反;做坐标、裁剪运算时要对齐,避免把行列搞反。

2. cv2.imshow / cv2.waitKey / cv2.destroyAllWindows — 显示图像

函数签名

cv2.imshow(winname, mat) -> None
cv2.waitKey(delay=0) -> int
cv2.destroyAllWindows() -> None
参数 类型 含义
winname str 窗口名;同名窗口会被复用 / 覆盖
mat ndarray 要显示的图像(BGR 顺序)
delay int 等待毫秒数;0 = 无限等待按键,>0 = 等待该毫秒数(常用于视频逐帧)

返回值waitKey 返回按下的键的 ASCII 码(int),超时未按键返回 -1

cv2.imshow("demo", img)
key = cv2.waitKey(0)          # 0:无限等待,按任意键继续
cv2.destroyAllWindows()       # 关闭所有窗口;也可用 cv2.destroyWindow("demo") 关指定窗口
注意
imshow 之后必须调用 waitKey 窗口才会渲染——它同时驱动 GUI 事件循环;不调用窗口会一闪而过或空白。即便不想等待,也至少要 waitKey(1) 配一个短暂延时。

3. 颜色通道顺序:OpenCV 用 BGR,不是 RGB

OpenCV 载入的彩色图像通道顺序是 BGR(蓝-绿-红),而非多数库(PIL、matplotlib)使用的 RGB。若直接把 OpenCV 图像交给以 RGB 解读的库显示,会出现红蓝互换。

函数签名

cv2.cvtColor(src, code[, dst]) -> ndarray
参数 含义
src 输入图像
code 颜色空间转换码,见下表

常用转换码

code 作用
COLOR_BGR2RGB BGR → RGB(给 matplotlib / 人眼查看用)
COLOR_BGR2GRAY BGR → 灰度
COLOR_BGR2HSV BGR → HSV(后续色彩分割常用)
import matplotlib.pyplot as plt

rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)   # 转成 RGB 再交给 matplotlib
plt.imshow(rgb)
plt.show()
注意
OpenCV 内部处理全程使用 BGR,仅在"用其他库显示或导出给人看"时才转 RGB;算法处理阶段不必反复转换,转来转去反而容易出错。

4. cv2.imwrite — 保存图像

函数签名

cv2.imwrite(filename, img[, params]) -> bool
参数 类型 含义
filename str 保存路径,扩展名决定格式(.jpg / .png 等)
img ndarray 要保存的图像(BGR,直接存,无需转 RGB)
params list 可选,格式相关参数,如 JPEG 质量 [int(cv2.IMWRITE_JPEG_QUALITY), 95]

返回值:保存成功返回 True,失败返回 False

ok = cv2.imwrite("out.jpg", img)            # 直接存 BGR
ok = cv2.imwrite("out.jpg", img, [int(cv2.IMWRITE_JPEG_QUALITY), 95])

5. 中文路径的处理

cv2.imread 对含中文的路径在部分环境下会返回 None。改用 NumPy 读取文件字节、再经 cv2.imdecode 解码可规避。

函数签名

cv2.imdecode(buf, flags) -> ndarray | None
参数 类型 含义
buf ndarray 图像字节的一维 uint8 数组(由 np.fromfile 读取)
flags int imread 的读取模式
import numpy as np

def imread_zh(path):
    buf = np.fromfile(path, dtype=np.uint8)        # 按字节读文件,绕开中文路径
    img = cv2.imdecode(buf, cv2.IMREAD_COLOR)
    if img is None:
        raise FileNotFoundError(f"解码失败: {path}")
    return img

6. 完整示例

import cv2

# 读取并判空
img = cv2.imread("photo.jpg")
if img is None:
    raise SystemExit("读取失败,检查路径")

# 提取灰度图并保存
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("photo_gray.jpg", gray)

# 显示原图(BGR 直接交给 OpenCV,无需转换)
cv2.imshow("原图", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

print("原图尺寸:", img.shape, "| 灰度图尺寸:", gray.shape)

本讲要点

  • cv2.imread(path, flags):彩色默认 BGR;失败返回 None务必判空
  • img.shape 顺序为 (高, 宽, 通道)
  • imshow 之后必须 waitKey 才能渲染窗口。
  • OpenCV 用 BGR;交给 matplotlib / 人眼查看时用 cvtColor(..., COLOR_BGR2RGB) 转换。
  • 中文路径用 np.fromfile + cv2.imdecode 规避。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功