Python计算机视觉 第10章-OpenCV

Python计算机视觉 第10章-OpenCV

OpenCV 是一个C++ 库,用于(实时)处理计算视觉问题。实时处理计算机视觉的 C++ 库,最初由英特尔公司开发,现由 Willow Garage 维护。OpenCV 是在 BSD 许可下发布的开源库,这意味着它对于学术研究和商业应用是免费的。

10.1 OpenCV的Python接口

OpenCV(Open Source Computer Vision Library)是一个开源计算机视觉库,提供了大量的图像和视频处理功能。其 Python 接口使得用户能够方便地在 Python 中使用 OpenCV 的功能。OpenCV Python 接口通过 cv2 模块提供了对各种计算机视觉算法和工具的访问,包括图像处理、视频分析、机器学习等。

使用

#直接pip没法安装下来
pip install cv2

#需要按照如下命令安装才会成功
pip install opencv-python

如果安装速度太慢可以使用清华源:

pip install 包名 -i https://pypi.tuna.tsinghua.edu.cn/simple

10.2 OpenCV基础知识

主要功能:
  1. 图像读取和显示

    • 读取图像:cv2.imread()
    • 显示图像:cv2.imshow()
    • 保存图像:cv2.imwrite()
  2. 图像处理

    • 图像转换:cv2.cvtColor()
    • 图像平滑:cv2.GaussianBlur(), cv2.medianBlur()
    • 边缘检测:cv2.Canny()
  3. 几何变换

    • 图像缩放:cv2.resize()
    • 旋转和仿射变换:cv2.warpAffine()
    • 透视变换:cv2.warpPerspective()
  4. 特征检测与描述

    • 角点检测:cv2.cornerHarris()
    • 特征匹配:cv2.BFMatcher(), cv2.FlannBasedMatcher()
  5. 视频处理

    • 捕捉视频:cv2.VideoCapture()
    • 播放视频:cv2.imshow()(与图像处理相同)
  6. 机器学习与深度学习

    • 加载预训练模型:cv2.dnn.readNet()
    • 进行推理:cv2.dnn.forward()

示例代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

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

# 显示原图
cv2.imshow('Original Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

# 图像平滑
smoothed_image = cv2.GaussianBlur(gray_image, (5, 5), 0)

# 边缘检测
edges = cv2.Canny(smoothed_image, 100, 200)

# 显示处理结果
fig, axs = plt.subplots(1, 3, figsize=(15, 5))
axs[0].imshow(cv2.cvtColor(gray_image, cv2.COLOR_BGR2RGB), cmap='gray')
axs[0].set_title('Gray Image')
axs[0].axis('off')

axs[1].imshow(cv2.cvtColor(smoothed_image, cv2.COLOR_BGR2RGB), cmap='gray')
axs[1].set_title('Smoothed Image')
axs[1].axis('off')

axs[2].imshow(cv2.cvtColor(edges, cv2.COLOR_BGR2RGB), cmap='gray')
axs[2].set_title('Edges')
axs[2].axis('off')

plt.show()

处理结果如下:
在这里插入图片描述

实验图1 示例代码处理结果

其中:

  1. 读取图像cv2.imread('test.jpg)

  2. 转换为灰度图cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

  3. 图像平滑cv2.GaussianBlur(gray_image, (5, 5), 0)

  4. 边缘检测cv2.Canny(smoothed_image, 100, 200)

  5. 显示结果:使用 matplotlib 展示灰度图、平滑图像和边缘检测结果

10.3 处理视频

OpenCV 提供了全面的视频处理功能,主要包括以下几个方面:

  1. 读取视频

    • 打开视频文件或摄像头进行视频流读取。
    • 使用 cv2.VideoCapture() 进行视频捕捉。
  2. 显示视频

    • 显示视频帧或视频流。
    • 使用 cv2.imshow() 显示每一帧图像。
  3. 处理视频

    • 对视频帧进行各种图像处理操作,如颜色转换、滤镜应用、对象检测等。
  4. 写入视频

    • 将处理后的视频保存到文件中。
    • 使用 cv2.VideoWriter() 进行视频编写和保存。
  5. 视频属性获取

    • 获取视频的帧率、分辨率、总帧数等信息。
    • 通过 cv2.CAP_PROP_FPScv2.CAP_PROP_FRAME_WIDTHcv2.CAP_PROP_FRAME_HEIGHT 获取视频属性。
  6. 逐帧处理

    • 对每一帧进行个性化处理,例如去噪、边缘检测、特效添加等。
  7. 视频流处理

    • 实时处理来自摄像头的视频流,包括实时特效应用和流媒体处理。

这些功能使得 OpenCV 能够实现丰富的视频分析和处理任务,如视频编辑、运动跟踪、实时监控等。

10.4 跟踪

视频跟踪是计算机视觉中的一项重要任务,用于在视频序列中持续追踪特定的对象。OpenCV 提供了多种跟踪算法,可以用于实现目标跟踪功能。

主要功能:
  1. 初始化跟踪器

    • 使用预定义的跟踪器算法(如 KLT、MOSSE、CSRT 等)来初始化跟踪器。
  2. 目标检测

    • 在视频的第一帧中检测并确定要跟踪的目标区域。
  3. 跟踪目标

    • 在后续帧中持续追踪目标,更新目标的位置。
  4. 更新跟踪器

    • 根据每帧中的目标位置更新跟踪器。
  5. 可视化跟踪结果

    • 在视频帧上绘制跟踪结果,例如矩形框或轨迹。
常见跟踪器:
  • KLT(Kanade-Lucas-Tomasi)

    • 基于特征点跟踪的方法,适用于处理局部特征的目标。
  • MOSSE(Minimum Output Sum of Squared Error)

    • 基于相关滤波器的跟踪方法,速度快且适用于低分辨率目标。
  • CSRT(Discriminative Correlation Filter with Channel and Spatial Reliability)

    • 结合了通道和空间可靠性的跟踪方法,适用于处理尺度变化和遮挡情况。
  • MedianFlow

    • 基于光流的方法,适用于处理稳定的目标跟踪。

应用场景

  • 实时监控:跟踪视频监控中的运动目标。
  • 视频分析:分析运动对象的轨迹和行为。
  • 人机交互:在增强现实和虚拟现实中跟踪用户的动作。

通过这些跟踪功能,OpenCV 能够帮助实现高效的目标跟踪,广泛应用于安防、自动驾驶、运动分析等领域。

10.4.2 Lucas-Kanade 算法

Lucas-Kanade 算法 是一种经典的光流法,用于在视频序列中估计每一帧图像中像素的运动。它基于局部区域的假设,通过求解局部区域内光流的速度来实现目标的跟踪和运动估计。

核心思想
  1. 局部光流假设

    • 假设目标在连续帧之间的运动是局部一致的,即在小区域内所有像素的运动是相同的。
  2. 光流约束方程

    • 基于光流约束方程: I x u + I y v + I t = 0 I_x u + I_y v + I_t = 0 Ixu+Iyv+It=0
      其中, I x I_x Ix I y I_y Iy 分别是图像在 x x x y y y 方向上的梯度, I t I_t It 是时间梯度(图像亮度随时间的变化), u u u v v v 是光流的水平和垂直分量。
  3. 局部光流求解

    • 使用局部窗口内的像素梯度信息,通过最小二乘法来估计光流的速度。通常,采用 3 × 3 3 \times 3 3×3 的窗口进行光流的计算。
  4. 光流计算

    • 通过求解以下线性方程组得到光流速度:
      [ ∑ I x 2 ∑ I x I y ∑ I x I y ∑ I y 2 ] [ u v ] = − [ ∑ I x I t ∑ I y I t ] \begin{bmatrix} \sum I_x^2 & \sum I_x I_y \\ \sum I_x I_y & \sum I_y^2 \end{bmatrix} \begin{bmatrix} u \\ v \end{bmatrix} = - \begin{bmatrix} \sum I_x I_t \\ \sum I_y I_t \end{bmatrix} [Ix2IxIyIxIyIy2][uv]=[IxItIyIt]
      其中, ∑ \sum 表示在局部窗口内的积分。
优点
  • 准确性:在平滑和一致的区域内能够提供较高的准确性。
  • 实现简单:相对简单的数学模型,易于实现。
缺点
  • 对大位移敏感:在目标快速移动或存在较大位移的情况下,光流计算的准确性可能降低。
  • 需要平滑区域:算法在具有纹理的区域效果较好,对于平坦区域或重复纹理区域可能不够准确。
应用场景
  • 运动检测:估计视频序列中物体的运动。
  • 目标跟踪:在视频流中追踪特定目标的运动。
  • 光流估计:用于图像对齐、稳定化和动作分析等。

Lucas-Kanade 算法因其简单有效的特性,广泛应用于各种计算机视觉任务中,是视频处理和目标跟踪中的基础算法之一。

如图10-6所示:
在这里插入图片描述

图 10-6:通过 LKTrack 类利用 Lucas-Kanade 算法进行跟踪

10.5 更多实例

10.5.1 图像修复

图像修复是指对图像中丢失或损坏的部分进行重建的过程。这个过程不仅包括用于恢复丢失数据或损坏部分的算法,还包括在照片编辑应用程序中去除不需要的元素,如红眼或物体。图像修复旨在填补图像中的缺失区域,使其恢复到尽可能完整和自然的状态。

主要步骤:
  1. 标记损坏区域

    • 确定图像中需要修复的区域,通常通过掩模图像标记这些区域。掩模图像中的标记区域会指示需要修复的部分。
  2. 选择修复算法

    • 选择适当的图像修复算法。例如,均值填补(Inpainting)方法使用周围像素的信息来填补损坏区域。Navier-Stokes 算法和纹理合成等方法也可用于不同类型的图像修复。
  3. 应用修复算法

    • 利用所选的算法对损坏区域进行修复。算法会根据周围区域的图像数据来填补缺失部分。
  4. 处理结果

    • 对修复后的图像进行后处理,以确保修复区域与周围区域自然融合。检查和调整修复效果,以实现更好的视觉效果。
应用场景:
  • 图像恢复:修复老旧或损坏的照片,使其恢复到原始状态。
  • 去除红眼:在照片编辑中去除红眼效果。
  • 物体去除:在照片中去除不需要的物体或标记,填补被去除部分的图像信息。
  • 遮挡修复:处理由于遮挡或图像损坏导致的缺失区域。

图像修复技术可以有效地恢复图像的完整性和视觉质量,广泛应用于图像编辑、数字修复以及计算机视觉等领域。

如图10-8所示:
在这里插入图片描述

图 10-8:用 OpenCV 进行图像修复的示例。左图显示了由用户标记的“破损”区域。右图显示了经过图像修复后的结果

10.5.2 利用霍夫变换检测直线

霍夫变换 是一种经典的图像处理技术,用于检测图像中的直线或其他形状。霍夫变换通过将图像空间的直线检测转换为参数空间的峰值检测,从而实现直线的检测。

核心思想
  1. 直线方程

    • 在笛卡尔坐标系中,直线方程为 y = m x + c y = mx + c y=mx+c,其中 m m m 是斜率, c c c 是截距。
    • 在霍夫变换中,通常使用极坐标系表示直线: ρ = x cos ⁡ θ + y sin ⁡ θ \rho = x \cos \theta + y \sin \theta ρ=xcosθ+ysinθ
      其中, ρ \rho ρ 是直线到原点的距离, θ \theta θ 是直线的角度。
  2. 参数空间

    • 通过将每个图像中的点转换为参数空间中的直线表示,所有的直线将映射到参数空间中的一条曲线。
  3. 累加器

    • 在参数空间中,对每条曲线进行累加,形成一个累加器数组。直线的峰值对应于参数空间中的高响应值。
  4. 峰值检测

    • 在累加器中寻找峰值,这些峰值对应于图像中真实存在的直线。
霍夫变换步骤
  1. 边缘检测

    • 使用边缘检测算法(如 Canny 边缘检测)检测图像中的边缘点。
  2. 霍夫变换

    • 将每个边缘点转换为参数空间中的曲线,并在累加器中进行累加。
  3. 峰值检测

    • 在累加器中检测峰值,找到参数空间中的直线。
  4. 绘制直线

    • 根据检测到的直线参数,在原图像上绘制直线。
应用场景
  • 车道检测:用于自动驾驶系统中检测车道标线。
  • 建筑物结构分析:分析建筑物中的直线结构。
  • 图像校正:校正图像中的直线变形。

霍夫变换通过将图像空间中的问题转换到参数空间,能够有效检测直线,并广泛应用于各种计算机视觉任务中。

示例代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('img_1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 边缘检测
edges = cv2.Canny(gray, 50, 150)

# 霍夫变换检测直线
lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)

# 在图像上绘制直线
if lines is not None:
    for line in lines:
        rho, theta = line[0]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho
        x1 = int(x0 + 1000 * (-b))
        y1 = int(y0 + 1000 * (a))
        x2 = int(x0 - 1000 * (-b))
        y2 = int(y0 - 1000 * (a))
        cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)

# 显示结果
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Detected Lines')
plt.axis('off')
plt.show()

处理结果如下:
在这里插入图片描述

实验图2 直线检测结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值