基本图像操作
本章节介绍 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_COLOR | 1 | 彩色图像,忽略透明通道 |
IMREAD_GRAYSCALE | 0 | 灰度图像 |
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')
下一步
掌握了基本的图像操作后,下一章节我们将学习图像处理基础,包括几何变换、图像滤波和边缘检测等内容。