Opencv入门——图片

从代码进行学习

图片

在 OpenCV (Python) 中,图像被视为多维数组,这使得我们可以利用 NumPy 强大的数组操作能力来处理图像。理解图像的表示方式和基本操作是学习计算机视觉的关键。

# -*- coding: utf--8 -*-
"""
这是一个基础的OpenCV图像处理脚本,用于演示如何:
1. 导入必要的库 (OpenCV, NumPy)。
2. 从文件加载一张图像。
3. 检查图像是否加载成功。
4. 调整图像的尺寸。
5. 获取并打印图像的基本信息(高、宽、通道数)。
6. 创建一个可调整大小的窗口来显示图像。
7. 等待用户按键后关闭所有窗口。
"""

import numpy as np
import cv2

# 打印当前安装的OpenCV版本号,方便调试和确认环境
print("OpenCV Version:", cv2.__version__)

# --- 1. 读取图像 ---
# 使用 cv2.imread() 函数从指定路径读取图像。
# r'...' 是一个原始字符串 (raw string),可以防止路径中的反斜杠'\'被错误地解析。

# 不同的读取模式 (flags):
# 模式1: cv2.IMREAD_COLOR (默认)
#   - 加载彩色图像,忽略任何透明度信息 (Alpha通道)。
#   - 图像通常有3个颜色通道,顺序为 BGR (蓝、绿、红)。
# img = cv2.imread(r'D:\path\to\your\messi5.jpg', cv2.IMREAD_COLOR)

# 模式2: cv2.IMREAD_GRAYSCALE
#   - 以灰度模式加载图像。
#   - 彩色图像会被自动转换为灰度图,图像只有1个通道。
# img = cv2.imread(r'D:\path\to\your\messi5.jpg', cv2.IMREAD_GRAYSCALE)

# 模式3: cv2.IMREAD_UNCHANGED
#   - 加载图像的原始数据,包括Alpha(透明)通道。
#   - 对于带透明背景的PNG图片等,这将加载为4个通道 (BGRA)。
img = cv2.imread(r'D:\OpenCV-Python-Tutorial-master\OpenCV-Python-Tutorial-master\ch04-Image\messi5.jpg', cv2.IMREAD_UNCHANGED)


# --- 2. 错误检查 ---
# cv2.imread() 如果失败,会返回 None。这是一个非常重要的健壮性检查。
if img is None:
    print("错误:无法加载图像!请检查:")
    print("1. 图像路径是否正确。")
    print("2. 图像文件是否存在且未损坏。")
    exit()  # 如果图像加载失败,则退出程序,防止后续代码出错。


# --- 3. 图像预处理 ---
# 使用 cv2.resize() 将图像尺寸统一调整为 宽度=640, 高度=480。
# 注意:dsize 参数的格式是 (宽度, 高度)。
img = cv2.resize(img, (640, 480))


# --- 4. 获取并打印图像信息 ---
# img.shape 返回一个元组,包含了图像的维度信息。
# 对于彩色图(含Alpha),格式为 (高度, 宽度, 通道数)。
# 对于灰度图,格式为 (高度, 宽度)。
# 这里用一个 try-except 结构来处理灰度图没有通道数的情况,让代码更健壮。
try:
    rows, cols, ch = img.shape
    print(f'图像尺寸: {cols}x{rows} (宽x高)')
    print(f'通道数: {ch}')
except ValueError:
    rows, cols = img.shape
    print(f'图像尺寸: {cols}x{rows} (宽x高)')
    print('通道数: 1 (灰度图)')

# **关键概念:图像的 高度(height) 对应数组的 行数(rows),宽度(width) 对应数组的 列数(cols)。**


# --- 5. 创建和管理显示窗口 ---
# 使用 cv2.namedWindow() 创建一个窗口,可以预先设置窗口属性。
# 'image' 是窗口的唯一标识符/名称。
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
# cv2.WINDOW_NORMAL:     用户可以自由调整窗口大小。
# cv2.WINDOW_AUTOSIZE:   窗口大小根据图像大小自动调整,且用户无法手动更改。这是默认选项。
# cv2.WINDOW_KEEPRATIO:  在调整窗口大小时,保持图像的原始宽高比。

# cv2.resizeWindow() 用于程序性地改变窗口大小。
# **注意:此函数只有在创建窗口时使用 cv2.WINDOW_NORMAL 标志才有效。**
# 如果窗口是 WINDOW_AUTOSIZE,则此函数不起作用。
# cv2.resizeWindow('image', 800, 600)


# --- 6. 显示图像 ---
# 在名为 'image' 的窗口中显示我们的图像数据 (img)。
cv2.imshow('image', img)


# --- 7. 等待用户输入 ---
# cv2.waitKey() 是一个关键函数,它负责处理窗口事件并等待键盘输入。
# 如果没有这行代码,窗口会一闪而过甚至不显示。
# delay=0: 表示无限期地等待,直到用户按下任意一个键。
# 它会返回被按下的键的ASCII码值,可以用于实现交互,例如:
# key = cv2.waitKey(0)
# if key == ord('s'):  # 如果按下 's' 键
#     cv2.imwrite('saved_image.png', img)
cv2.waitKey(0)


# --- 8. 清理和释放资源 ---
# 销毁所有由OpenCV创建的窗口,这是一个良好的编程习惯。
cv2.destroyAllWindows()


# --- 9. (可选) 保存图像 ---
# 使用 cv2.imwrite() 可以将处理后的图像保存到磁盘。
# 注意:如果文件 'messigray.png' 已存在,它将被直接覆盖,不会有任何提示。
# cv2.imwrite('messigray.png', img)

1. 图像的本质:NumPy 数组 (numpy.ndarray)
  • 数据结构:在 OpenCV for Python 中,图像被加载后会存储为一个 NumPy 的多维数组 (numpy.ndarray)。这使得图像处理操作可以高效地利用 NumPy 库的优化。
  • 像素值:数组中的每个元素代表图像中的一个像素点。像素值通常是 0 到 255 之间的整数(uint8 类型),其中 0 通常代表黑色,255 通常代表白色(对于灰度图)或某个颜色通道的最大亮度。
  • 维度:图像的维度由其颜色通道决定:
    • 灰度图:通常是二维数组,形状为 (高度, 宽度)(高度, 宽度, 1)。每个元素直接表示像素的亮度值。
    • 彩色图:通常是三维数组,形状为 (高度, 宽度, 通道数)。例如,BGR 图像的形状是 (高度, 宽度, 3)
2. 图像的基本属性 (img.shape)

当图像被加载为 NumPy 数组后,我们可以通过访问其 shape 属性来获取其基本信息:

  • img.shape:返回一个元组,通常包含以下信息:

    • 高度 (rows):图像的行数,对应垂直方向的像素数量。
    • 宽度 (cols):图像的列数,对应水平方向的像素数量。
    • 通道数 (ch):图像的颜色通道数量。
      • 1:表示灰度图(单通道)。
      • 3:表示彩色图(如 BGR 通道)。
      • 4:表示带有 Alpha 通道(透明度)的图像(如 BGRA 通道)。

    例如,rows, cols, ch = img.shape 可以方便地解包这些信息。

3. 颜色空间与通道
  • BGR (Blue, Green, Red)
    • OpenCV 在处理彩色图像时,默认的通道顺序是 蓝色 (B)绿色 (G)红色 ®。这与我们常见的 RGB 顺序不同。
    • 当加载彩色图像(IMREAD_COLORIMREAD_UNCHANGED 且图像有颜色通道)时,NumPy 数组的第三个维度对应着这些通道。
  • 灰度 (Grayscale)
    • 通过 cv2.IMREAD_GRAYSCALE 标志加载的图像是单通道的。
    • 每个像素只有一个亮度值,通常在 0 (黑) 到 255 (白) 之间。
  • Alpha 通道 (透明度)
    • 当使用 cv2.IMREAD_UNCHANGED 标志加载图像时,如果原始图像格式支持透明度(如 PNG),并且包含 Alpha 通道,那么它也会被加载进来。
    • 此时,图像的通道数会是 4 (BGRA),第四个通道表示像素的透明度(0 为完全透明,255 为完全不透明)。
4. 图像的读取与写入
  • cv2.imread(filename, flags)
    • 功能:从指定路径读取图像文件。
    • filename:图像文件的路径。为了避免路径中反斜杠的转义问题,建议使用原始字符串(r'path\to\image.jpg')。
    • flags (读取模式)
      • cv2.IMREAD_COLOR (或 1): 读取彩色图像,忽略 Alpha 通道。默认值。
      • cv2.IMREAD_GRAYSCALE (或 0): 读取灰度图像。
      • cv2.IMREAD_UNCHANGED (或 -1): 读取图像,包括所有通道(包括 Alpha 通道)。
    • 返回值:成功返回 NumPy 数组 (图像数据),失败返回 None
    • 错误检查:务必使用 if img is None: 来检查图像是否成功加载,以增强程序的健壮性。
  • cv2.imwrite(filename, img, params)
    • 功能:将图像数据保存到指定文件。
    • filename:要保存的文件名(含路径和扩展名)。
    • img:要保存的图像 NumPy 数组。
    • 覆盖行为:如果 filename 已经存在,cv2.imwrite()直接覆盖现有文件,不会给出提示。
5. 图像的尺寸调整 (cv2.resize)
  • cv2.resize(src, dsize, fx, fy, interpolation)
    • 功能:调整图像的大小。
    • src:原始图像。
    • dsize:目标图像的尺寸元组 (宽度, 高度)
    • fx, fy (可选): 缩放因子。如果指定 dsize,则通常不需要。
    • interpolation (可选): 插值方法。影响缩放质量和速度,默认是 INTER_LINEAR
    • 用途:统一图像大小,适应显示需求,或为后续处理做准备。
6. 图像的显示与窗口管理
  • cv2.namedWindow(winname, flags)
    • 功能:创建一个显示图像的窗口。
    • winname:窗口的名称,是唯一的标识符。
    • flags (窗口属性)
      • cv2.WINDOW_NORMAL: 窗口大小可调整。
      • cv2.WINDOW_AUTOSIZE: 窗口大小自动适应图像,不可调整(默认值)。
      • cv2.WINDOW_KEEPRATIO: 调整窗口大小时保持图像比例(通常与 WINDOW_NORMAL 结合使用)。
    • 多窗口:使用不同的 winname 可以创建并管理多个独立的图像显示窗口。
  • cv2.imshow(winname, mat)
    • 功能:在指定的窗口中显示图像。
    • winname:要显示图像的窗口名称(必须先通过 namedWindow 创建或由 imshow 隐式创建)。
    • mat:要显示的图像数据 (NumPy 数组)。
    • 刷新机制imshow() 只是准备好图像,真正的显示和刷新需要结合 cv2.waitKey()
  • cv2.waitKey(delay)
    • 功能:等待键盘事件,并刷新所有 OpenCV 窗口。
    • delay (毫秒)
      • 0:无限等待,直到用户按下任意键。
      • >0:等待指定毫秒数。在这段时间内如果按下键,返回键的 ASCII 值;否则返回 -1
    • 重要性必须cv2.imshow() 之后调用 cv2.waitKey(),否则窗口可能一闪而过或根本不显示。
  • cv2.destroyAllWindows()
    • 功能:销毁所有由 OpenCV 创建的 GUI 窗口。
    • 用途:在程序结束时释放资源,是一个良好的编程习惯。
7. 其他重要概念
  • import numpy as npNumPy 是 OpenCV 在 Python 中进行图像数据处理的基础库,其 ndarray 是图像的核心数据类型。
  • import cv2:这是 OpenCV 库在 Python 中的入口点,所有图像处理函数都通过它访问。
  • 版本信息print(cv2.__version__) 可以帮助你了解当前使用的 OpenCV 版本,这在调试和解决兼容性问题时非常有用。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐