OpenCV 图像基本操作
本教程(中文)专注于 OpenCV 图像基本操作,涵盖读取、显示、保存图像,访问和修改像素,颜色通道操作,图像属性获取,以及基本的 ROI(感兴趣区域)处理等内容。基于 Python 的 opencv-python 库,提供清晰的代码示例和解释,适合初学者快速上手。本教程假设你已安装 OpenCV,并使用 imgcodecs 和 highgui 模块进行基础操作。
一、图像基本操作概述
- 图像表示:OpenCV 中图像以 NumPy 数组表示,形状为
(height, width, channels),默认使用 BGR 颜色格式。 - 基本操作:
- 读取和保存图像(
imread,imwrite)。 - 显示图像(
imshow,waitKey)。 - 访问和修改像素值。
- 通道操作:拆分、合并、转换颜色空间。
- 获取图像属性:尺寸、数据类型、像素总数。
- ROI 裁剪:提取图像子区域。
二、核心操作与代码示例
以下逐一讲解每个基本操作,提供 Python 示例代码。
2.1 读取图像
使用 cv2.imread 读取图像,支持 JPG、PNG、BMP 等格式。
import cv2
import numpy as np
# 读取图像
img = cv2.imread('lena.jpg') # 替换为你的图像路径
# 检查是否加载成功
if img is None:
print("错误:无法加载图像,请检查文件路径")
else:
print(f"图像加载成功,形状: {img.shape}") # 输出 (高度, 宽度, 通道数)
输出示例:
图像加载成功,形状: (512, 512, 3)
说明:
imread参数:cv2.IMREAD_COLOR:默认,加载 BGR 彩色图像。cv2.IMREAD_GRAYSCALE:加载灰度图像。cv2.IMREAD_UNCHANGED:加载图像并保留 alpha 通道。- 始终检查返回值,防止路径错误。
2.2 显示图像
使用 cv2.imshow 显示图像,cv2.waitKey 等待用户输入。
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# 显示图像
cv2.imshow('图像', img)
key = cv2.waitKey(0) # 等待按键,0 表示无限等待
if key == ord('q'): # 按 'q' 退出
print("退出显示")
cv2.destroyAllWindows() # 关闭所有窗口
说明:
imshow:创建窗口显示图像,窗口名称为第一个参数。waitKey:控制窗口显示时间,0表示等待用户按键。destroyAllWindows:释放窗口资源。
2.3 保存图像
使用 cv2.imwrite 保存图像到文件。
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# 保存图像
success = cv2.imwrite('output.jpg', img)
if success:
print("图像已保存为 output.jpg")
else:
print("错误:无法保存图像")
说明:
imwrite:支持多种格式,文件名扩展名决定编码(如.jpg,.png)。- 可设置压缩参数,例如 JPG 质量:
cv2.imwrite('output_high_quality.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 95])
2.4 访问和修改像素
图像是 NumPy 数组,可通过索引访问和修改像素值。
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# 访问像素 (y=100, x=100)
pixel = img[100, 100] # 返回 [B, G, R]
print(f"像素(100,100): {pixel}")
# 修改像素为绿色
img[100, 100] = [0, 255, 0]
# 访问单个通道
blue = img[100, 100, 0] # 蓝色通道
print(f"蓝色通道值: {blue}")
# 修改一块区域为红色
img[50:100, 50:100] = [0, 0, 255] # 设置为红色
# 显示修改后的图像
cv2.imshow('修改后的图像', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出示例:
像素(100,100): [110 156 210]
蓝色通道值: 110
说明:
- 像素格式:
img[y, x]返回[B, G, R](BGR 顺序)。 - 通道索引:
img[y, x, c],其中c=0(蓝)、c=1(绿)、c=2(红)。
2.5 通道操作
拆分、合并通道或转换颜色空间。
示例:拆分和合并通道
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# 拆分通道
b, g, r = cv2.split(img)
# 显示各通道
cv2.imshow('蓝色通道', b)
cv2.imshow('绿色通道', g)
cv2.imshow('红色通道', r)
# 合并通道
img_merged = cv2.merge([b, g, r])
cv2.imshow('合并后的图像', img_merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 修改蓝色通道并合并
b[:] = 0 # 将蓝色通道置零
img_no_blue = cv2.merge([b, g, r])
cv2.imwrite('no_blue.jpg', img_no_blue)
说明:
split:将图像拆分为三个通道(B、G、R),返回单通道图像。merge:合并通道,需保持通道顺序。
示例:颜色空间转换
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# BGR -> 灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# BGR -> HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 显示结果
cv2.imshow('灰度图像', gray)
cv2.imshow('HSV图像', hsv)
cv2.waitKey(0)
cv2.destroyAllWindows()
说明:
cvtColor:转换颜色空间,常见选项包括COLOR_BGR2GRAY、COLOR_BGR2HSV。
2.6 获取图像属性
获取图像的形状、数据类型和像素总数等信息。
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# 图像属性
print(f"形状: {img.shape}") # (高度, 宽度, 通道数)
print(f"数据类型: {img.dtype}") # 通常 uint8
print(f"像素总数: {img.size}") # 高度 * 宽度 * 通道数
print(f"维度: {img.ndim}") # 2(灰度)或 3(彩色)
输出示例:
形状: (512, 512, 3)
数据类型: uint8
像素总数: 786432
维度: 3
2.7 ROI(感兴趣区域)裁剪
提取图像的子区域。
import cv2
img = cv2.imread('lena.jpg')
if img is None:
print("错误:无法加载图像")
exit()
# 裁剪 ROI (y=100:200, x=100:200)
roi = img[100:200, 100:200]
# 显示和保存 ROI
cv2.imshow('ROI', roi)
cv2.imwrite('roi.jpg', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
说明:
- ROI 通过 NumPy 数组切片实现:
img[y_start:y_end, x_start:x_end]。
三、综合示例:图像操作流水线
结合读取、显示、修改像素、通道操作和 ROI:
import cv2
import numpy as np
def process_image(image_path):
"""图像处理流水线"""
# 读取图像
img = cv2.imread(image_path)
if img is None:
print("错误:无法加载图像")
return
# 获取属性
print(f"形状: {img.shape}, 数据类型: {img.dtype}")
# 修改像素(将 (100,100) 设为绿色)
img[100, 100] = [0, 255, 0]
# 拆分和合并通道
b, g, r = cv2.split(img)
b[:] = 0 # 移除蓝色通道
img_no_blue = cv2.merge([b, g, r])
# 裁剪 ROI
roi = img[100:300, 100:300]
# 转换为灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 显示结果
cv2.imshow('原始图像', img)
cv2.imshow('无蓝色通道', img_no_blue)
cv2.imshow('ROI', roi)
cv2.imshow('灰度图像', gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存结果
cv2.imwrite('no_blue.jpg', img_no_blue)
cv2.imwrite('roi.jpg', roi)
cv2.imwrite('gray.jpg', gray)
# 使用示例
process_image('lena.jpg') # 替换为你的图像路径
输出示例:
形状: (512, 512, 3), 数据类型: uint8
四、注意事项
- 颜色格式:
- OpenCV 使用 BGR 格式,与 Matplotlib 的 RGB 不同,需转换(如
COLOR_BGR2RGB)。
- 错误处理:
- 始终检查
imread返回值,防止路径错误。 - 确保图像格式受支持(如 JPG、PNG)。
- 内存管理:
- 使用
destroyAllWindows()关闭窗口,释放资源。 - 处理大图像时,考虑内存使用量。
- 性能优化:
- 像素操作(如循环)较慢,尽量使用 NumPy 矢量化操作。
- ROI 操作可减少计算量。
- 文件路径:
- 使用绝对路径或确保相对路径正确。
- Windows 用户注意路径分隔符(
\\或/)。
五、资源
- 官方文档:https://docs.opencv.org/master/d4/df6/tutorial_py_basic_ops.html
- Python 教程:https://opencv-python-tutroals.readthedocs.io/
- 社区:在 X 平台搜索
#opencv获取最新讨论。
如果你需要更深入的操作(如批量处理图像、复杂像素操作)或 C++ 实现代码,请告诉我,我可以提供针对性的示例或进一步优化!