跳到主要内容

基本图像操作

本章节介绍 OpenCV 中最基础的操作:图像的读取、显示、保存以及图像的基本属性。

图像读取

OpenCV 使用 cv2.imread() 函数读取图像文件。

基本用法

import cv2

# 读取图像
image = cv2.imread('image.jpg')

# 检查图像是否读取成功
if image is None:
print("图像读取失败,请检查文件路径")
else:
print(f"图像读取成功,尺寸: {image.shape}")

imread() 函数返回一个 NumPy 数组,如果读取失败则返回 None。读取失败通常是因为文件路径错误或文件格式不支持。

读取模式

imread() 函数的第二个参数指定读取模式:

# 彩色图像(默认)
color_image = cv2.imread('image.jpg', cv2.IMREAD_COLOR)

# 灰度图像
gray_image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 包含透明通道
rgba_image = cv2.imread('image.jpg', cv2.IMREAD_UNCHANGED)

# 任意深度
any_depth = cv2.imread('image.jpg', cv2.IMREAD_ANYDEPTH)

# 任意颜色
any_color = cv2.imread('image.jpg', cv2.IMREAD_ANYCOLOR)

常用的读取模式说明:

模式数值说明
IMREAD_COLOR1彩色图像,忽略透明通道
IMREAD_GRAYSCALE0灰度图像
IMREAD_UNCHANGED-1包含透明通道的原始图像

文件路径处理

在 Windows 系统中,路径分隔符可能导致问题,建议使用原始字符串或正斜杠:

# 使用原始字符串
image = cv2.imread(r'C:\Users\name\images\test.jpg')

# 使用正斜杠
image = cv2.imread('C:/Users/name/images/test.jpg')

# 使用 os.path 模块
import os
path = os.path.join('images', 'test.jpg')
image = cv2.imread(path)

图像显示

OpenCV 使用 cv2.imshow() 函数显示图像。

基本显示

import cv2

image = cv2.imread('image.jpg')

# 创建窗口并显示图像
cv2.imshow('窗口标题', image)

# 等待按键,0 表示无限等待
cv2.waitKey(0)

# 关闭所有窗口
cv2.destroyAllWindows()

cv2.waitKey() 函数等待键盘事件,参数是等待时间(毫秒)。传入 0 表示无限等待,直到有按键按下。函数返回按键的 ASCII 码。

多图像显示

可以同时显示多个图像:

import cv2

image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')

cv2.imshow('图像1', image1)
cv2.imshow('图像2', image2)

cv2.waitKey(0)
cv2.destroyAllWindows()

窗口控制

import cv2

image = cv2.imread('image.jpg')

# 创建可调整大小的窗口
cv2.namedWindow('可调整窗口', cv2.WINDOW_NORMAL)
cv2.imshow('可调整窗口', image)

# 创建自动大小的窗口
cv2.namedWindow('自动大小窗口', cv2.WINDOW_AUTOSIZE)
cv2.imshow('自动大小窗口', image)

cv2.waitKey(0)
cv2.destroyAllWindows()

响应键盘事件

import cv2

image = cv2.imread('image.jpg')
cv2.imshow('图像', image)

while True:
key = cv2.waitKey(0) & 0xFF # 获取按键 ASCII 码

if key == ord('q'): # 按 q 退出
break
elif key == ord('s'): # 按 s 保存
cv2.imwrite('saved_image.jpg', image)
print("图像已保存")
elif key == 27: # 按 ESC 退出
break

cv2.destroyAllWindows()

注意:waitKey(0) & 0xFF 是为了兼容 64 位系统,确保返回正确的 ASCII 码。

图像保存

使用 cv2.imwrite() 函数保存图像。

基本保存

import cv2

image = cv2.imread('input.jpg')

# 保存为 JPEG 格式
cv2.imwrite('output.jpg', image)

# 保存为 PNG 格式
cv2.imwrite('output.png', image)

OpenCV 根据文件扩展名自动确定保存格式。

保存参数

可以指定保存参数来控制图像质量:

import cv2

image = cv2.imread('input.jpg')

# JPEG 质量(0-100,默认95)
cv2.imwrite('output.jpg', image, [cv2.IMWRITE_JPEG_QUALITY, 90])

# PNG 压缩级别(0-9,默认3)
cv2.imwrite('output.png', image, [cv2.IMWRITE_PNG_COMPRESSION, 6])

JPEG 质量参数说明:

  • 数值越大,图像质量越高,文件体积越大
  • 推荐值:90(高质量)、75(中等质量)、50(低质量)

PNG 压缩级别说明:

  • 数值越大,压缩率越高,保存速度越慢
  • 推荐值:3(默认)、6(较高压缩)、9(最高压缩)

图像属性

图像在 OpenCV 中以 NumPy 数组形式存储,可以通过数组属性获取图像信息。

基本属性

import cv2

image = cv2.imread('image.jpg')

# 图像尺寸 (高度, 宽度, 通道数)
print(f"形状: {image.shape}")

# 图像数据类型
print(f"数据类型: {image.dtype}")

# 像素总数
print(f"像素总数: {image.size}")

# 维度数
print(f"维度: {image.ndim}")

输出示例:

形状: (480, 640, 3)
数据类型: uint8
像素总数: 921600
维度: 3

理解图像形状

对于彩色图像,shape 返回 (height, width, channels)

  • height:图像高度(像素行数)
  • width:图像宽度(像素列数)
  • channels:通道数(彩色图像为 3,灰度图像不返回此项)
import cv2

# 彩色图像
color = cv2.imread('image.jpg', cv2.IMREAD_COLOR)
print(f"彩色图像: {color.shape}") # (480, 640, 3)

# 灰度图像
gray = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
print(f"灰度图像: {gray.shape}") # (480, 640)

像素访问

可以像访问 NumPy 数组一样访问像素值:

import cv2

image = cv2.imread('image.jpg')

# 获取单个像素值 (B, G, R)
pixel = image[100, 200]
print(f"像素值 (B, G, R): {pixel}")

# 获取单个通道的值
blue = image[100, 200, 0]
green = image[100, 200, 1]
red = image[100, 200, 2]
print(f"蓝: {blue}, 绿: {green}, 红: {red}")

# 修改像素值
image[100, 200] = [255, 255, 255] # 设置为白色

注意:OpenCV 使用 BGR 格式存储彩色图像,而不是 RGB 格式。这是 OpenCV 的历史原因,使用时需要注意。

区域访问

使用 NumPy 的切片功能访问图像区域:

import cv2

image = cv2.imread('image.jpg')

# 获取感兴趣区域 (ROI)
roi = image[100:200, 150:250] # [y1:y2, x1:x2]

# 显示 ROI
cv2.imshow('ROI', roi)
cv2.waitKey(0)

# 复制 ROI 到其他位置
image[300:400, 350:450] = roi

颜色空间转换

OpenCV 提供了 cv2.cvtColor() 函数进行颜色空间转换。

BGR 转 RGB

由于 OpenCV 使用 BGR 格式,而 Matplotlib 使用 RGB 格式,显示时需要转换:

import cv2
import matplotlib.pyplot as plt

image = cv2.imread('image.jpg')

# BGR 转 RGB
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 使用 Matplotlib 显示
plt.imshow(rgb_image)
plt.axis('off')
plt.show()

BGR 转灰度

import cv2

image = cv2.imread('image.jpg')

# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

cv2.imshow('灰度图像', gray)
cv2.waitKey(0)

BGR 转 HSV

HSV 颜色空间更适合颜色分割任务:

import cv2

image = cv2.imread('image.jpg')

# 转换为 HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

cv2.imshow('HSV 图像', hsv)
cv2.waitKey(0)

HSV 各通道含义:

  • H (Hue):色调,范围 0-179
  • S (Saturation):饱和度,范围 0-255
  • V (Value):明度,范围 0-255

完整示例

下面是一个完整的示例,演示图像读取、显示、转换和保存:

import cv2

def process_image(input_path, output_path):
# 读取图像
image = cv2.imread(input_path)

if image is None:
print(f"无法读取图像: {input_path}")
return

# 打印图像信息
print(f"图像尺寸: {image.shape[1]}x{image.shape[0]}")
print(f"通道数: {image.shape[2] if len(image.shape) == 3 else 1}")

# 转换为灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 显示原图和灰度图
cv2.imshow('原图', image)
cv2.imshow('灰度图', gray)

# 等待按键
key = cv2.waitKey(0)

# 按 s 保存灰度图
if key == ord('s'):
cv2.imwrite(output_path, gray)
print(f"灰度图已保存到: {output_path}")

cv2.destroyAllWindows()

# 使用示例
process_image('input.jpg', 'output_gray.jpg')

下一步

掌握了基本的图像操作后,下一章节我们将学习图像处理基础,包括几何变换、图像滤波和边缘检测等内容。