OpenCV(全称:Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,旨在为开发者提供一套高效的工具来处理图像和视频分析任务。
主要功能
-
图像处理
-
基础操作:裁剪、缩放、旋转、颜色转换(如RGB转灰度)。
-
高级处理:边缘检测(Canny算法)、图像滤波(降噪)、直方图均衡化。
-
-
视频分析
-
实时视频流处理(如摄像头输入)、运动检测、背景分割、光流跟踪。
-
-
物体检测与识别
-
内置预训练模型(如Haar级联、HOG)支持人脸、行人、车辆检测。
-
支持深度学习框架(TensorFlow、PyTorch)的模型集成,用于更复杂的识别任务(如YOLO目标检测)。
-
-
3D重建
-
立体视觉(通过多摄像头生成深度图)、点云处理、结构光扫描。
-
-
机器学习工具
-
提供K-means聚类、支持向量机(SVM)等算法,用于图像分类或数据标注。
-
学习资源
-
看这篇“OpenCV功法”(python版)
环境安装
pip install opencv-python
导入OpenCV
import cv2
验证安装
import cv2
print(cv2.__version__) # 应输出版本号(如4.11.0)
认识图像
1. 图像的底层结构
-
基本单位:图像由 像素(Pixel) 组成,每个像素的值表示颜色或亮度。
-
数据格式:默认使用
numpy.ndarray
类型的多维数组表示。
import cv2
img = cv2.imread("images/changli.png")
print(type(img)) # 输出: <class 'numpy.ndarray'>
2. 图像数组的维度
图像的维度由 颜色通道 和 分辨率 决定:
-
灰度图:二维数组
(height, width)
,每个元素是0~255
的整数(8位无符号整型uint8
)。
import cv2
img = cv2.imread("images/changli.png")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度化
print(gray_img.shape) # 示例输出: (234, 384)
-
彩色图:三维数组
(height, width, channels)
,通道顺序为 BGR(注意不是常见的 RGB!)
import cv2
img = cv2.imread("images/changli.png")
print(img.shape) # 示例输出: (234, 384, 3)
BGR 与 RGB 的区别
-
OpenCV 默认使用 BGR 顺序,而其他库(如 Matplotlib)通常使用 RGB。
3. 数据类型与范围
-
默认类型为
uint8
(0~255)
使用图像
图像读取
在 OpenCV (Python) 中,读取图像主要通过 cv2.imread()
函数实现。以下是详细说明和常见用法:
1. 基本语法
import cv2
# img = cv2.imread("图像路径", 读取模式)
img = cv2.imread("images/changli.png", cv2.IMREAD_COLOR)
-
参数说明:
-
图像路径
:字符串类型,支持绝对路径(如D:/images/cat.jpg
)或相对路径(如../data/image.png
)。 -
读取模式
:可选标志(默认为cv2.IMREAD_COLOR
,即彩色模式)。
-
2. 读取模式详解
通过 cv2.imread()
的第二个参数控制图像加载方式:
模式常量 | 值 | 作用 |
---|---|---|
cv2.IMREAD_COLOR | 1 | 默认,加载彩色图像(忽略透明度) |
cv2.IMREAD_GRAYSCALE | 0 | 加载灰度图像 |
cv2.IMREAD_UNCHANGED | -1 | 加载图像包含 Alpha 通道(透明度) |
import cv2
color_img = cv2.imread("images/changli.png") # 彩色模式(等效于 cv2.IMREAD_COLOR)
gray_img = cv2.imread("images/changli.png", cv2.IMREAD_GRAYSCALE) # 灰度模式
alpha_img = cv2.imread("images/changli.png", cv2.IMREAD_UNCHANGED) # 保留透明度(PNG适用)
窗体创建
在 OpenCV (Python) 中,创建窗体(窗口)是显示图像、视频或交互界面的基础操作。以下是详细的创建窗体方法及功能扩展:
1. 基础窗体创建
创建命名窗体:cv2.namedWindow("窗体名称", 标志)
标志 | 用户调整大小 | 图像自适应窗口 | 典型用途 |
---|---|---|---|
WINDOW_AUTOSIZE | ❌ | ✔️ | 快速显示固定尺寸图像 |
WINDOW_NORMAL | ✔️ | ❌ | 需要手动/编程控制窗口大小 |
WINDOW_FULLSCREEN | ❌ | ❌ | 全屏演示(如幻灯片播放) |
2. 窗体属性设置
调整窗体大小和位置
import cv2
img = cv2.imread("images/changli.png")
cv2.imshow("img", img)
cv2.namedWindow("Custom Window", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Custom Window", 800, 600) # 设置初始宽高
cv2.moveWindow("Custom Window", 0, 200) # 移动窗体到屏幕坐标 (x=100, y=200)
全屏显示
import cv2
img = cv2.imread("images/changli.png")
cv2.imshow("img", img)
cv2.namedWindow("Fullscreen", cv2.WINDOW_NORMAL)
cv2.setWindowProperty("Fullscreen", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow("Fullscreen", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像显示
在 OpenCV (Python) 中显示图像是计算机视觉任务的基础操作。以下是详细步骤和常见应用场景的代码实现:
1. 基础显示流程
import cv2
# 读取图像
img = cv2.imread("images/changli.png") # 默认彩色模式
# 创建窗口(可选,默认会自动创建)
cv2.namedWindow("Image Display")
# 显示图像
cv2.imshow("Image Display", img)
# 等待按键(0=无限等待,单位毫秒)
key = cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
2. 多窗口同时显示
import cv2
img1 = cv2.imread("images/cat1.png")
img2 = cv2.imread("images/changli.png")
cv2.imshow("Window 1", img1)
cv2.imshow("Window 2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. 视频流显示
import cv2
cap = cv2.VideoCapture(0) # 0代表打开默认摄像头。也可以打开视频文件,如:cap = cv2.VideoCapture("video.mp4")
while True:
ret, frame = cap.read()
if not ret:
break
# 显示原始帧和结果
cv2.imshow("Original", frame)
if cv2.waitKey(1) == 27: # ESC退出
break
cap.release()
cv2.destroyAllWindows()
图像大小调整
在 OpenCV (Python) 中调整图像大小主要通过 cv2.resize()
函数实现。以下是详细的用法说明、插值方法选择以及保持宽高比的技巧:
1. 基础语法
import cv2
# 读取图像
img = cv2.imread("input.jpg")# 调整大小
resized = cv2.resize(src=img, dsize=(width, height), fx=scale_x, fy=scale_y, interpolation=方法)
-
核心参数:
-
dsize
:目标尺寸(width, height)
,注意顺序是宽度在前,高度在后。 -
fx
和fy
:沿 x 和 y 轴的缩放因子(若指定dsize
,则fx/fy
会被忽略)。 -
interpolation
:插值方法(决定缩放质量,默认为cv2.INTER_LINEAR
)。
-
2. 调整方式示例
方式一:指定目标尺寸
# 缩放到 400x300 像素
resized = cv2.resize(img, (400, 300))
方式二:按比例缩放
# 宽度缩小一半,高度缩小一半
scale_percent = 50 # 50% 缩放
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
resized = cv2.resize(img, (width, height))
3. 插值方法详解
不同插值方法影响缩放后的图像质量与速度:
插值方法 | 适用场景 | 速度 | 质量 |
---|---|---|---|
cv2.INTER_NEAREST | 最快,适合实时处理 | ⚡️⚡️ | 低 |
cv2.INTER_LINEAR | 默认,平衡速度与质量(推荐) | ⚡️ | 中 |
cv2.INTER_CUBIC | 高质量放大(4x4 像素邻域) | 🐢 | 高 |
cv2.INTER_AREA | 适合缩小图像(避免波纹效应) | ⚡️ | 中高 |
cv2.INTER_LANCZOS4 | 最高质量放大(8x8 像素邻域) | 🐢🐢 | 最高 |
5. 完整流程示例
import cv2
# 读取图像
img = cv2.imread("images/changli.png")
if img is None:
raise FileNotFoundError("图像未找到!")
# 等比例缩放到宽度 800 像素
target_width = 800
aspect_ratio = target_width / img.shape[1]
target_height = int(img.shape[0] * aspect_ratio)
# 使用高质量插值方法
resized = cv2.resize(img, (target_width, target_height), interpolation=cv2.INTER_AREA)
# 显示结果
cv2.imshow("Original", img)
cv2.imshow("Resized", resized)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存调整后的图像
cv2.imwrite("resized_output.jpg", resized)
图像存储
在 OpenCV (Python) 中,使用 cv2.imwrite()
函数保存图像。
import cv2
# 读取图像并转换为灰度
img = cv2.imread("images/changli.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测边缘
edges = cv2.Canny(gray, 100, 200)
# 保存边缘检测结果
if cv2.imwrite("edges.jpg", edges):
print("保存成功!")
else:
print("保存失败,请检查路径或权限。")
-
参数说明:
-
保存路径
:字符串类型,支持绝对或相对路径(如output.jpg
或results/processed.png
)。 -
图像数组
:必须为 NumPy 数组格式(即 OpenCV 读取的图像数据)。
-
-
返回值:
success
为布尔值,True
表示保存成功。
图像绘制
在 OpenCV (Python) 中,可以通过多种函数在图像上绘制图形、文字和标注。以下是常见绘制操作的详细指南和代码示例:
1. 基本图形绘制
绘制线段
import cv2
import numpy as np# 创建空白图像(500x500像素,3通道BGR,白色背景)
img = np.ones((500, 500, 3), dtype=np.uint8) * 255# 绘制红色线段(起点(50,50),终点(400,400),线宽5,抗锯齿)
cv2.line(img, (50,50), (400,400), (0,0,255), 5, cv2.LINE_AA)
绘制矩形
# 绘制绿色矩形(左上角(100,100),右下角(300,300),线宽2)
cv2.rectangle(img, (100,100), (300,300), (0,255,0), 2)# 填充矩形(线宽设为 -1)
cv2.rectangle(img, (200,200), (400,400), (255,0,0), -1)
绘制圆形
# 绘制黄色圆(圆心(250,250),半径50,线宽3)
cv2.circle(img, (250,250), 50, (0,255,255), 3)# 填充圆(线宽 -1)
cv2.circle(img, (350,150), 30, (255,0,255), -1)
绘制箭头
# 从 (400,50) 到 (450,100),线宽2,尖端比例0.5
cv2.arrowedLine(img, (400,50), (450,100), (0,0,0), 2, tipLength=0.5)
绘制椭圆
# 中心(150,350),长轴100,短轴50,旋转角度30°,起始角度0~360°
cv2.ellipse(img, (150,350), (100,50), 30, 0, 360, (128,128,128), 2)
2. 文字绘制
# 添加文字(左下角起点(50,450),字体、大小、颜色、线宽)
text = "Hello OpenCV!"
cv2.putText(img, text, (50,450),
fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=1.5,
color=(0,0,0),
thickness=2,
lineType=cv2.LINE_AA)
关键参数说明
参数 | 含义 |
---|---|
color | BGR 元组(如红色为 (0,0,255) ) |
thickness | 线宽(-1 表示填充图形) |
lineType | 线型(cv2.LINE_AA 为抗锯齿,cv2.LINE_8 为默认快速绘制) |
fontFace | 字体类型(如 cv2.FONT_HERSHEY_SIMPLEX ) |
fontScale | 字体大小 |
注意事项
-
坐标顺序:OpenCV 使用 (x,y) 坐标(宽度在前,高度在后),而非 NumPy 数组的
(行,列)
。 -
颜色模式:确保颜色值为 BGR 格式(如红色是
(0,0,255)
,而非 RGB 的(255,0,0)
)。 -
图像备份:绘制操作会直接修改原图,如需保留原始图像,先使用
img.copy()
复制。