使用 Python OpenCV 进行实时距离估算

pythonserver side programmingprogramming更新于 2024/1/13 11:08:00

Python 和 OpenCV 彻底改变了计算机视觉领域,使开发人员和研究人员能够探索广泛的应用。凭借其简单性、多功能性和广泛的库支持,Python 已成为包括计算机视觉在内的各个领域的流行编程语言。作为 Python 功能的补充,OpenCV(开源计算机视觉库)提供了强大的图像和视频处理工具包,使其成为实现计算机视觉算法的首选。

在本文中,我们将指导您完成设置开发环境、捕获实时视频源、校准摄像头以及使用 OpenCV 实现对象检测和跟踪技术的过程。然后,我们将探索各种距离计算方法,包括三角测量,并展示如何无缝集成这些技术以实时估算物体之间的距离。在本文的下一部分中,我们将介绍相机校准的基础知识及其在距离估计中的重要性。

使用 Python OpenCV 进行实时距离估计

首先,我们需要安装 OpenCV 及其依赖项。

安装 Python:如果您尚未安装 Python,请前往 Python 官方网站 (python.org) 并下载与您的操作系统兼容的最新版本。

安装 OpenCV:可以使用 pip 等包管理器安装 OpenCV。打开终端或命令提示符并运行以下命令:

pip install opencv-python

此命令将下载并安装适用于 Python 的 OpenCV 包。

安装其他库:除了 OpenCV,我们还将为该项目使用其他 Python 库。通过运行以下 pip 命令安装它们:

pip install numpy
pip install matplotlib

NumPy 是一个功能强大的数值计算库,而 Matplotlib 则可用于可视化数据和显示图像。

通过使用 OpenCV 访问摄像头源来捕获实时视频

要执行实时距离估计,我们首先需要使用 OpenCV 访问摄像头源。幸运的是,OpenCV 提供了简单的函数来完成此任务。在本教程中,我们将使用 `VideoCapture` 类,它允许我们从相机捕获视频帧。

以下是示例代码片段,演示了如何访问相机源:

import cv2

# 创建 VideoCapture 对象
cap = cv2.VideoCapture(0)

# 检查相机是否已成功打开
if not cap.isOpened():
    print("Failed to open the camera")
    exit()

# 读取并显示来自相机的帧
while True:
    ret, frame = cap.read()
    if not ret:
        print("Failed to read frame from the camera")
        break

    # 显示帧
    cv2.imshow("Camera Feed", frame)
    
    # 如果按下"q",则中断循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放 VideoCapture 对象并关闭窗口
cap.release()
cv2.destroyAllWindows()

在上面的代码中,我们访问了摄像机源。现在让我们了解如何跟踪对象。

OpenCV 中的对象检测和跟踪

对象检测是计算机视觉中的一项关键任务,涉及在图像或视频流中定位和分类对象。OpenCV 提供了几种用于对象检测的算法,包括 Haar 级联和方向梯度直方图 (HOG)。

Haar 级联:Haar 级联是经过训练的分类器,可根据特定视觉特征(例如边缘、角落和纹理图案)检测对象。这些分类器使用经过正样本和负样本训练的弱分类器级联来逐步缩小感兴趣对象的搜索空间。

HOG(方向梯度直方图):HOG 是一种特征描述符,可捕获局部对象外观和形状信息。它通过计算和分析图像中梯度方向的分布来工作。

在本教程中,我们将重点介绍使用 OpenCV 的基于 Haar 级联的对象检测方法。以下是演示视频流中的对象检测和跟踪的示例代码片段:

import cv2

# 加载预先训练的 Haar 级联分类器
cascade_path = "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)

# 访问摄像头源
cap = cv2.VideoCapture(0)

while True:
    # 从相机读取一帧
    ret, frame = cap.read()
    if not ret:
    print("无法从相机读取帧")
    break
    
    # 将帧转换为灰度
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # 在灰度帧中检测人脸
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    
    # 在检测到的人脸周围绘制矩形
    for (x, y, w, h) in faces:
    cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
    
    # 显示结果帧
    cv2.imshow("Object Detection", frame)
    
    # 如果按下"q",则中断循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放 VideoCapture 对象并关闭窗口
cap.release()
cv2.destroyAllWindows()

在上面的代码中,我们首先使用 OpenCV 提供的 `CascadeClassifier` 类加载 Haar 级联分类器进行人脸检测。您可以尝试使用不同的预训练 Haar 级联和参数来检测其他对象或提高检测精度。

使用三角测量计算距离

三角测量是一种广泛使用的基于几何和透视原理的距离估计方法。三角测量涉及使用视差概念和已知几何关系来计算距离。

OpenCV 提供了函数和工具来轻松实现三角测量算法。以下是使用 OpenCV 演示立体三角测量的示例代码片段:

import cv2
import numpy as np

# 加载相机校准参数
camera_matrix_1 = np.load("camera_matrix_1.npy")
dist_coeff_1 = np.load("dist_coeff_1.npy")
camera_matrix_2 = np.load("camera_matrix_2.npy")
dist_coeff_2 = np.load("dist_coeff_2.npy")
R = np.load("rotation_matrix.npy")
T = np.load("translation_vector.npy")

# 加载每个视图中的相应图像点
image_points_1 = np.load("image_points_1.npy")
image_points_2 = np.load("image_points_2.npy")

# 执行立体三角测量
points_4d = cv2.triangulatePoints(camera_matrix_1, camera_matrix_2, image_points_1, image_points_2)

# 将 4D 齐次坐标转换为 3D 笛卡尔坐标
points_3d = cv2.convertPointsFromHomogeneous(points_4d.T)

# 提取 X、Y 和 Z 坐标
x = points_3d[:, 0, 0]
y = points_3d[:, 0, 1]
z = points_3d[:, 0, 2]

# 计算距离
distances = np.sqrt(x**2 + y**2 + z**2)

# 打印计算出的距离
for i, distance in enumerate(distances):
    print(f"Point {i+1} distance: {distance}")

在上面的代码中,我们实现了用于距离计算的三角测量算法。通过使用 OpenCV 实现这些三角测量算法,我们可以在实时应用中准确估计距离。

实时距离估计

现在我们已经介绍了物体检测、相机校准和距离计算的各个组件,是时候将所有内容整合在一起并创建一个完整的实时距离估计系统了。

我们的实时距离估计应用程序的代码实现如下所示:

import cv2
import numpy as np

# 加载相机校准参数
camera_matrix_1 = np.load("camera_matrix_1.npy")
dist_coeff_1 = np.load("dist_coeff_1.npy")
camera_matrix_2 = np.load("camera_matrix_2.npy")
dist_coeff_2 = np.load("dist_coeff_2.npy")
R = np.load("rotation_matrix.npy")
T = np.load("translation_vector.npy")

# 加载预先训练的 Haar 级联分类器
cascade_path = "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)

# 访问相机源
cap = cv2.VideoCapture(0)

while True:
    # 从相机读取一帧
    ret, frame = cap.read()
    if not ret:
        print("无法从相机读取帧")
        break
    
    # 将帧转换为灰度
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # 在灰度帧中检测人脸
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

    for (x, y, w, h) in faces:
        # 计算用于三角测量的二维图像点
        image_points_1 = np.array([[x, y+h/2]], dtype=np.float32)
        image_points_2 = np.array([[x+w, y+h/2]], dtype=np.float32)
        
        # 执行立体三角测量
        points_4d = cv2.triangulatePoints(camera_matrix_1, camera_matrix_2, image_points_1, image_points_2)
        
        # 将四维齐次坐标转换为三维笛卡尔坐标
        points_3d = cv2.convertPointsFromHomogeneous(points_4d.T)
        
        # 提取 X、Y 和 Z 坐标
        x = points_3d[0, 0, 0]
        y = points_3d[0, 0, 1]
        z = points_3d[0, 0, 2]
        
        # 计算距离
        distance = np.sqrt(x**2 + y**2 + z**2)
        
        # 绘制边界框并在框上显示距离
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
        cv2.putText(frame, f"Distance: {distance:.2f} unit", (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

    # 显示结果帧
    cv2.imshow("实时距离估计", frame)
    
    # 如果按下"q",则中断循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放捕获并关闭窗口
cap.release()
cv2.destroyAllWindows()

在上面的代码中,我们已成功使用 Python 和 OpenCV 实现了实时距离估计应用程序。

结论

在本教程中,我们学习了如何使用 Python 和 OpenCV 执行实时距离估计。通过结合对象检测、跟踪和三角测量技术,我们创建了一个完整的系统,用于实时估计对象之间的距离。借助提供的代码示例,您现在可以探索各种领域的应用程序,例如机器人技术、增强现实和安全系统。尽情探索计算机视觉的激动人心的可能性吧!


相关文章