如何使用OpenCV-Python进行图像处理?
使用 OpenCV-Python 进行图像处理的详尽指南
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它包含了超过2500种优化算法,可用于各种图像和视频处理任务。OpenCV 跨平台支持,可以在 Windows、Linux、macOS、iOS 和 Android 上运行。OpenCV 提供了多种语言的接口,包括 C++、Java 和 Python。其中,OpenCV-Python 是 OpenCV 的 Python API,它结合了 OpenCV C++ API 的高效性和 Python 语言的易用性。
本文将深入探讨如何使用 OpenCV-Python(通常简称为 cv2
)进行各种图像处理操作。我们将从基础的图像读取和显示开始,逐步深入到更高级的技术,如滤波、边缘检测、形态学操作、特征检测、对象跟踪等。
1. 安装 OpenCV-Python
最简单的安装方法是使用 pip:
bash
pip install opencv-python
如果你需要包含一些额外的贡献模块(例如 SIFT、SURF 等,这些模块可能受专利保护),可以使用:
bash
pip install opencv-contrib-python
2. 基础图像操作
2.1 读取图像
使用 cv2.imread()
函数读取图像文件。它接受两个参数:
- 文件名(包括路径):指定要读取的图像文件的路径。
- 标志(可选):指定图像读取模式。常见的标志有:
cv2.IMREAD_COLOR
(或 1): 默认值,加载彩色图像(忽略透明度通道)。cv2.IMREAD_GRAYSCALE
(或 0): 加载灰度图像。cv2.IMREAD_UNCHANGED
(或 -1): 加载图像,包括透明度通道(如果有)。
```python
import cv2
读取彩色图像
img_color = cv2.imread('image.jpg', cv2.IMREAD_COLOR)
读取灰度图像
img_gray = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
读取图像,包括透明度通道
img_unchanged = cv2.imread('image.png', cv2.IMREAD_UNCHANGED)
检查是否成功读取
if img_color is None:
print("Error: Could not read the image.")
```
2.2 显示图像
使用 cv2.imshow()
函数显示图像。它接受两个参数:
- 窗口名称:一个字符串,用作显示图像的窗口的标题。
- 图像:要显示的图像(NumPy 数组)。
cv2.imshow()
通常与 cv2.waitKey()
和 cv2.destroyAllWindows()
结合使用:
cv2.waitKey(delay)
: 等待指定的毫秒数,直到按下键盘上的任意键。如果delay
为 0,则无限期等待。cv2.destroyAllWindows()
: 销毁所有打开的 OpenCV 窗口。cv2.destroyWindow(windowName)
: 销毁指定名称的窗口。
```python
import cv2
img = cv2.imread('image.jpg')
if img is not None:
cv2.imshow('Image', img) # 显示图像,窗口标题为 'Image'
cv2.waitKey(0) # 等待按键,无限期
cv2.destroyAllWindows() # 关闭所有窗口
```
2.3 保存图像
使用 cv2.imwrite()
函数保存图像。它接受两个参数:
- 文件名:要保存的图像文件的路径和名称(包括扩展名)。
- 图像:要保存的图像(NumPy 数组)。
```python
import cv2
img = cv2.imread('image.jpg')
if img is not None:
cv2.imwrite('output.png', img) # 将图像保存为 PNG 格式
```
2.4 图像属性
图像在 OpenCV 中表示为 NumPy 数组。你可以通过以下属性访问图像的属性:
img.shape
: 返回一个元组,表示图像的尺寸(高度、宽度、通道数)。- 对于灰度图像,通道数为 1。
- 对于彩色图像(BGR 格式),通道数为 3。
img.size
: 返回图像的总像素数(高度 * 宽度 * 通道数)。img.dtype
: 返回图像的数据类型(例如uint8
、float32
等)。
python
import cv2
img = cv2.imread('image.jpg')
if img is not None:
print("Shape:", img.shape) # 输出: (高度, 宽度, 通道数)
print("Size:", img.size) # 输出: 总像素数
print("Data type:", img.dtype) # 输出: 数据类型
3. 色彩空间转换
OpenCV 默认以 BGR(蓝、绿、红)颜色空间读取图像。你可以使用 cv2.cvtColor()
函数在不同的色彩空间之间进行转换。常见的色彩空间转换包括:
- BGR 到灰度:
cv2.COLOR_BGR2GRAY
- BGR 到 HSV:
cv2.COLOR_BGR2HSV
- BGR 到 RGB:
cv2.COLOR_BGR2RGB
- RGB 到 BGR:
cv2.COLOR_RGB2BGR
(在某些情况下可能需要, 比如你使用了matplotlib)
```python
import cv2
img = cv2.imread('image.jpg')
if img is not None:
# BGR 到灰度
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# BGR 到 HSV
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# BGR 到 RGB (如果你需要 RGB 格式)
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
cv2.imshow('Gray Image', gray_img)
cv2.imshow('HSV Image', hsv_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
4. 几何变换
4.1 缩放
使用 cv2.resize()
函数调整图像大小。
```python
import cv2
img = cv2.imread('image.jpg')
if img is not None:
# 缩放到指定的宽度和高度
resized_img = cv2.resize(img, (500, 400)) # 宽度 500, 高度 400
# 按比例缩放
scaled_img = cv2.resize(img, None, fx=0.5, fy=0.5) # 缩小一半
cv2.imshow('Resized Image', resized_img)
cv2.imshow('Scaled Image', scaled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
4.2 平移
平移是沿 x 和 y 轴移动图像。你可以使用仿射变换来实现平移。
```python
import cv2
import numpy as np
img = cv2.imread('image.jpg')
if img is not None:
rows, cols, _ = img.shape
# 定义平移矩阵
M = np.float32([[1, 0, 50], [0, 1, 30]]) # 向右移动 50 像素, 向下移动 30 像素
# 应用仿射变换
translated_img = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('Translated Image', translated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
4.3 旋转
旋转也是一种仿射变换。OpenCV 提供了 cv2.getRotationMatrix2D()
函数来生成旋转矩阵。
```python
import cv2
import numpy as np
img = cv2.imread('image.jpg')
if img is not None:
rows, cols, _ = img.shape
# 获取旋转矩阵 (中心点, 旋转角度, 缩放因子)
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1) # 以图像中心旋转 45 度
# 应用仿射变换
rotated_img = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('Rotated Image', rotated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
4.4 仿射变换
仿射变换是保持图像中直线和平行性的变换。你可以使用 cv2.getAffineTransform()
通过指定三个点的对应关系来创建仿射变换矩阵。
```python
import cv2
import numpy as np
img = cv2.imread('image.jpg')
if img is not None:
rows, cols, ch = img.shape
# 原图像中的三个点
pts1 = np.float32([[50,50],[200,50],[50,200]])
# 变换后图像中对应的三个点
pts2 = np.float32([[10,100],[200,50],[100,250]])
# 生成仿射变换矩阵
M = cv2.getAffineTransform(pts1,pts2)
# 应用仿射变换
dst = cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('Affine Transform', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
4.5 透视变换
透视变换可以改变图像的视角。你可以使用 cv2.getPerspectiveTransform()
通过指定四个点的对应关系来创建透视变换矩阵, 然后使用 cv2.warpPerspective()
应用变换。
```python
import cv2
import numpy as np
img = cv2.imread('image.jpg')
if img is not None:
rows, cols, ch = img.shape
# 原图像中的四个点
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
# 变换后图像中对应的四个点
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
# 生成透视变换矩阵
M = cv2.getPerspectiveTransform(pts1,pts2)
# 应用透视变换
dst = cv2.warpPerspective(img,M,(300,300))
cv2.imshow('Perspective Transform', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
5. 图像阈值处理
阈值处理是将图像分割成不同区域的常用方法。OpenCV 提供了 cv2.threshold()
函数和 cv2.adaptiveThreshold()
函数。
5.1 cv2.threshold()
cv2.threshold()
函数应用固定级别的阈值。
```python
import cv2
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
if img is not None:
# 二值化阈值处理 (大于阈值的像素设为 255, 小于阈值的像素设为 0)
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 反二值化阈值处理 (大于阈值的像素设为 0, 小于阈值的像素设为 255)
ret, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
# 截断阈值处理 (大于阈值的像素设为阈值, 小于阈值的像素保持不变)
ret, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
# 阈值处理为 0 (小于阈值的像素设为 0, 大于阈值的像素保持不变)
ret, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
# 反阈值处理为 0 (大于阈值的像素设为 0, 小于阈值的像素保持不变)
ret, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
cv2.imshow('Original', img)
cv2.imshow('Binary', thresh1)
cv2.imshow('Binary Inv', thresh2)
cv2.imshow('Trunc', thresh3)
cv2.imshow('To Zero', thresh4)
cv2.imshow('To Zero Inv', thresh5)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
5.2 cv2.adaptiveThreshold()
cv2.adaptiveThreshold()
函数根据图像局部区域的特性自适应地计算阈值。
```python
import cv2
img = cv2.imread('sudoku.jpg', cv2.IMREAD_GRAYSCALE) # 使用一张有明暗变化的图片
if img is not None:
# 中值滤波 (去除椒盐噪声)
img = cv2.medianBlur(img, 5)
# 自适应阈值处理 (均值方法)
thresh1 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \
cv2.THRESH_BINARY, 11, 2)
# 自适应阈值处理 (高斯方法)
thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \
cv2.THRESH_BINARY, 11, 2)
cv2.imshow('Original', img)
cv2.imshow('Adaptive Mean', thresh1)
cv2.imshow('Adaptive Gaussian', thresh2)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
6. 图像平滑(滤波)
图像平滑(或模糊)用于减少图像中的噪声和细节。OpenCV 提供了多种滤波器。
6.1 均值滤波
cv2.blur()
或 cv2.boxFilter()
python
import cv2
img = cv2.imread('noisy_image.jpg')
if img is not None:
# 使用 5x5 均值滤波器
blur = cv2.blur(img, (5, 5))
cv2.imshow('Original', img)
cv2.imshow('Blurred', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
6.2 高斯滤波
cv2.GaussianBlur()
python
import cv2
img = cv2.imread('noisy_image.jpg')
if img is not None:
# 使用 5x5 高斯滤波器, 标准差为 0 (自动计算)
gaussian_blur = cv2.GaussianBlur(img, (5, 5), 0)
cv2.imshow('Original', img)
cv2.imshow('Gaussian Blurred', gaussian_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
6.3 中值滤波
cv2.medianBlur()
(对椒盐噪声特别有效)
```python
import cv2
img = cv2.imread('salt_pepper_noise.jpg') # 加载有椒盐噪声的图像
if img is not None:
# 使用 5x5 中值滤波器
median_blur = cv2.medianBlur(img, 5)
cv2.imshow('Original', img)
cv2.imshow('Median Blurred', median_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
6.4 双边滤波
cv2.bilateralFilter()
(在保持边缘清晰的同时平滑图像)
python
import cv2
img = cv2.imread('image.jpg')
if img is not None:
# 使用双边滤波器 (直径, 颜色空间标准差, 坐标空间标准差)
bilateral_filtered = cv2.bilateralFilter(img, 9, 75, 75)
cv2.imshow('Original', img)
cv2.imshow('Bilateral Filtered', bilateral_filtered)
cv2.waitKey(0)
cv2.destroyAllWindows()
7. 形态学操作
形态学操作是基于图像形状的一组图像处理操作。它们通常用于二值图像(例如,阈值处理后的图像),但也可以用于灰度图像。
7.1 腐蚀
cv2.erode()
(缩小前景对象的边界)
```python
import cv2
import numpy as np
img = cv2.imread('j.png', cv2.IMREAD_GRAYSCALE) # 使用一个简单的二值图像
if img is not None:
# 创建一个 5x5 的矩形结构元素
kernel = np.ones((5, 5), np.uint8)
# 应用腐蚀
erosion = cv2.erode(img, kernel, iterations=1)
cv2.imshow('Original', img)
cv2.imshow('Erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
7.2 膨胀
cv2.dilate()
(扩大前景对象的边界)
```python
import cv2
import numpy as np
img = cv2.imread('j.png', cv2.IMREAD_GRAYSCALE)
if img is not None:
# 创建一个 5x5 的矩形结构元素
kernel = np.ones((5, 5), np.uint8)
# 应用膨胀
dilation = cv2.dilate(img, kernel, iterations=1)
cv2.imshow('Original', img)
cv2.imshow('Dilation', dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
7.3 开运算
cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
(先腐蚀后膨胀,用于去除小的对象或噪声)
```python
import cv2
import numpy as np
img = cv2.imread('opening.png', cv2.IMREAD_GRAYSCALE) # 使用一个包含小噪声的图像
if img is not None:
# 创建一个 5x5 的矩形结构元素
kernel = np.ones((5, 5), np.uint8)
# 应用开运算
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('Original', img)
cv2.imshow('Opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
7.4 闭运算
cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
(先膨胀后腐蚀,用于填充小的孔洞)
```python
import cv2
import numpy as np
img = cv2.imread('closing.png', cv2.IMREAD_GRAYSCALE) # 使用一个包含小孔洞的图像
if img is not None:
# 创建一个 5x5 的矩形结构元素
kernel = np.ones((5, 5), np.uint8)
# 应用闭运算
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow('Original', img)
cv2.imshow('Closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
7.5 形态学梯度
cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
(膨胀和腐蚀之间的差,用于提取对象的边缘)
7.6 顶帽
cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
(原图像与开运算结果的差,用于提取比周围更亮的区域)
7.7 黑帽
cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
(闭运算结果与原图像的差,用于提取比周围更暗的区域)
8. 边缘检测
边缘检测用于识别图像中亮度变化明显的区域。
8.1 Sobel 算子
cv2.Sobel()
(计算图像在 x 和 y 方向上的梯度)
```python
import cv2
img = cv2.imread('sudoku.jpg', cv2.IMREAD_GRAYSCALE)
if img is not None:
# 计算 x 方向上的梯度 (垂直边缘)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
# 计算 y 方向上的梯度 (水平边缘)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)
# 计算梯度幅值
abs_grad_x = cv2.convertScaleAbs(sobelx)
abs_grad_y = cv2.convertScaleAbs(sobely)
grad = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)
cv2.imshow('Original', img)
cv2.imshow('Sobel X', abs_grad_x)
cv2.imshow('Sobel Y', abs_grad_y)
cv2.imshow('Sobel Combined', grad)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
8.2 Scharr 算子
cv2.Scharr()
Sobel算子的增强版, 对细小边缘更敏感
8.3 Laplacian 算子
cv2.Laplacian()
(计算图像的二阶导数,对边缘更敏感)
```python
import cv2
img = cv2.imread('sudoku.jpg', cv2.IMREAD_GRAYSCALE)
if img is not None:
# 计算 Laplacian 梯度
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian) # 需要转回 uint8 才能显示
cv2.imshow('Original', img)
cv2.imshow('Laplacian', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
8.4 Canny 边缘检测
cv2.Canny()
(一种多阶段的边缘检测算法,效果通常更好)
```python
import cv2
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
if img is not None:
# 使用 Canny 边缘检测 (低阈值, 高阈值)
edges = cv2.Canny(img, 100, 200)
cv2.imshow('Original', img)
cv2.imshow('Canny Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
9. 轮廓检测
轮廓检测用于查找图像中对象的边界。
```python
import cv2
img = cv2.imread('shapes.png') # 使用一个包含多个形状的图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
if img is not None:
# 阈值处理 (将图像二值化)
ret, thresh = cv2.threshold(img_gray, 127, 255, 0)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# contours 是一个列表, 包含所有找到的轮廓
# hierarchy 包含轮廓的层级关系
# 绘制轮廓
cv2.drawContours(img, contours, -1, (0, 255, 0), 3) # -1 表示绘制所有轮廓, (0,255,0) 是绿色, 3 是线宽
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
10. 直方图
直方图是图像中像素强度分布的图形表示。
10.1 计算直方图
cv2.calcHist()
```python
import cv2
import matplotlib.pyplot as plt # 导入 matplotlib 用于绘图
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
if img is not None:
# 计算直方图 ([图像], [通道], 掩码, [直方图大小], [像素范围])
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
# 使用 matplotlib 绘制直方图
plt.plot(hist)
plt.show()
```
10.2 直方图均衡化
cv2.equalizeHist()
(增强图像的对比度)
```python
import cv2
img = cv2.imread('low_contrast.jpg', cv2.IMREAD_GRAYSCALE) # 使用一张低对比度的图像
if img is not None:
# 应用直方图均衡化
equalized_img = cv2.equalizeHist(img)
cv2.imshow('Original', img)
cv2.imshow('Equalized', equalized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
11. 特征检测与描述
特征检测和描述是计算机视觉中的一个重要领域,用于识别图像中的关键点和特征,以便进行图像匹配、对象识别等任务。OpenCV 提供了多种特征检测和描述算法。
- Harris 角点检测:
cv2.cornerHarris()
- Shi-Tomasi 角点检测:
cv2.goodFeaturesToTrack()
- SIFT (Scale-Invariant Feature Transform):
cv2.SIFT_create()
(可能需要在opencv-contrib-python
中) - SURF (Speeded-Up Robust Features):
cv2.SURF_create()
(可能需要在opencv-contrib-python
中) - ORB (Oriented FAST and Rotated BRIEF):
cv2.ORB_create()
由于 SIFT 和 SURF 算法可能受专利保护,它们可能不在标准的 OpenCV 安装中。如果需要使用它们,请确保安装了 opencv-contrib-python
。
下面是一个使用 ORB 特征检测和描述的示例:
```python
import cv2
img1 = cv2.imread('box.png', cv2.IMREAD_GRAYSCALE) # 目标图像
img2 = cv2.imread('box_in_scene.png', cv2.IMREAD_GRAYSCALE) # 场景图像
if img1 is not None and img2 is not None:
# 创建 ORB 对象
orb = cv2.ORB_create()
# 检测关键点并计算描述符
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# 创建 BFMatcher (Brute-Force Matcher) 对象
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 匹配描述符
matches = bf.match(des1, des2)
# 根据距离排序匹配
matches = sorted(matches, key=lambda x: x.distance)
# 绘制最佳匹配
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow("Matches", img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
12. 视频处理
OpenCV 不仅可以处理静态图像,还可以处理视频。
12.1 读取视频
cv2.VideoCapture()
```python
import cv2
从文件读取视频
cap = cv2.VideoCapture('video.mp4')
从摄像头读取视频 (0 表示默认摄像头)
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Error: Could not open video.")
exit()
while True:
# 读取一帧
ret, frame = cap.read()
# 如果成功读取到帧
if ret:
# 在此处进行帧处理 (例如,转换为灰度)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 显示帧
cv2.imshow('Video', gray_frame)
# 按 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
释放资源
cap.release()
cv2.destroyAllWindows()
```
12.2 写入视频
cv2.VideoWriter()
```python
import cv2
cap = cv2.VideoCapture('video.mp4')
if not cap.isOpened():
print("Error opening video stream or file")
获取视频的宽度和高度
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
定义编解码器并创建 VideoWriter 对象
fourcc = cv2.VideoWriter_fourcc(*'XVID') # 或使用其他编解码器
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (frame_width, frame_height))
while cap.isOpened():
ret, frame = cap.read()
if ret:
# 在此处进行帧处理
# 写入处理后的帧
out.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
释放资源
cap.release()
out.release()
cv2.destroyAllWindows()
```
13. 对象跟踪
OpenCV提供了几种对象跟踪算法, 下面是一个使用 cv2.TrackerCSRT_create()
的例子:
```python
import cv2
读取视频
cap = cv2.VideoCapture("video.mp4")
创建跟踪器
tracker = cv2.TrackerCSRT_create()
读取第一帧
ret, frame = cap.read()
选择要跟踪的对象 (使用鼠标选择一个矩形区域)
bbox = cv2.selectROI("Tracking", frame, False)
初始化跟踪器
tracker.init(frame, bbox)
def drawBox(img,bbox):
x, y, w, h = int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])
cv2.rectangle(img, (x, y), ((x + w), (y + h)), (255, 0, 255), 3, 3 )
cv2.putText(img, "Tracking", (100, 75), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
while True:
timer = cv2.getTickCount()
ret, frame = cap.read()
if not ret:
break;
# 更新跟踪器
success, bbox = tracker.update(frame)
# 绘制跟踪框
if success:
drawBox(frame,bbox)
else:
cv2.putText(frame, "Lost", (100, 75), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# 计算并显示 FPS
fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer)
cv2.putText(frame, str(int(fps)), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.imshow("Tracking", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
```
总结
OpenCV-Python 是一个功能强大且易于使用的图像处理库。本文只是介绍了 OpenCV 的一部分功能,但涵盖了许多常见的图像处理任务。要充分利用 OpenCV 的潜力,建议深入研究 OpenCV 的官方文档和示例,并根据你的具体需求探索更高级的功能。 记住,图像处理是一个实践性很强的领域,最好的学习方法是动手实践!