OpenCV 跟踪

Salman Mehmood 2024年2月15日
OpenCV 跟踪

本演示旨在学习如何使用 Python 和 OpenCV 创建一个非常基本且简单的运动检测和跟踪系统。我们在本文末尾实现了用矩形边界框跟踪每个人。

使用 Python 和 OpenCV 创建运动检测和跟踪系统

首先,我们需要从 CAP 实例中读取两个帧。

ret, F1 = CAP.read()

同样,我们将阅读第二帧。

ret, F2 = CAP.read()

现在我们将声明一个名为 DF 的变量并使用 absdiff() 函数。absdiff() 帮助找到帧之间的绝对差异,第一个 F1 和第二个 F2

while CAP.isOpened():
    if ret == False:
        print(ret)
        break
    DF = cv2.absdiff(F1, F2)

使用 cvtColor() 方法将此差异转换为灰度模式。第一个参数是 DF

第二个参数将是 COLOR_BGR2GRAY,这将有助于将帧颜色 BGR 转换为灰度模式;为什么我们要找出灰度模式?

因为我们会在后期找到轮廓,所以灰度模式比彩色模式更容易找到轮廓。

Gray_Scale = cv2.cvtColor(DF, cv2.COLOR_BGR2GRAY)

一旦我们有了灰度模式,我们需要使用 GaussianBlur() 方法来模糊我们的灰度帧。它需要一些参数;第一个是 Gray_Scale,第二个参数是内核大小 5x5,第三个参数是 Sigma X 值。

BL = cv2.GaussianBlur(Gray_Scale, (5, 5), 0)

我们需要使用 threshold() 方法来确定阈值。它返回两个对象;我们定义 _,因为我们不需要第一个变量,然后第二个变量将是 thresh

在第一个参数中,我们将我们的模糊图像作为源传递,然后第二个参数将是阈值 20。最大阈值为 255;类型将是 THRESH_BINARY

_, thresh = cv2.threshold(BL, 20, 255, cv2.THRESH_BINARY)

我们需要扩大阈值图像以填充所有孔;这将帮助我们找到更好的轮廓。dilate() 方法有几个参数;第一个参数将是定义的阈值,第二个参数将是内核大小,但我们将其传递给 None

第三个参数是迭代次数为 3。如果不起作用,你可以增加或减少迭代次数。

DL = cv2.dilate(thresh, None, iterations=3)

在下一步中,我们将找出轮廓,findContours() 方法为我们提供了两个结果;一个是轮廓,另一个是层次结构,但我们不打算使用第二个结果。我们将在膨胀图像上找到轮廓。

所以我们在第一个参数中传递扩张图像,接下来是最常用的 RETR_TREE 模式。下一个参数将是 CHAIN_APPROX_SIMPLE 方法。

CTS, _ = cv2.findContours(DL, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

在下一步中,我们要绘制矩形,因此我们将使用 for 循环遍历所有轮廓。CTS 是一个列表,我们正在迭代这个列表,所以第一步是使用 boundingRect() 方法保存轮廓的所有坐标。

下一步,我们将找出轮廓区域,如果这个区域小于某个值,我们将不会绘制矩形。在 for 循环中,我们将定义如果轮廓面积小于 700,我们将继续迭代;否则,绘制矩形。

要绘制矩形,我们需要使用 cv2.rectangle() 方法,这里的第一个参数将是源,即 F1;第二个参数将是点 1 (x,y)。第三个参数是点 2,下一个参数是作为颜色值的元组,下一个参数是厚度。

for CT in CTS:
    (x, y, w, h) = cv2.boundingRect(CT)

    if cv2.contourArea(CT) < 900:
        continue
    cv2.rectangle(F1, (x, y), (x + w, y + h), (0, 255, 0), 2)

如果观察到一些移动,我们将在图像上放置一些文本。我们将使用 cv2.putText() 方法;此方法将采用 F1,第二个将是文本,下一个参数参数将是我们要放置此文本的原点。

下一个参数是字体 FONT_HERSHEY_SIMPLEX;下一个参数将是字体比例。接下来是字体的颜色;然后,最后一个参数将是文本的粗细。

cv2.putText(
    F1,
    "Status: {}".format("Movement"),
    (10, 20),
    cv2.FONT_HERSHEY_SIMPLEX,
    1,
    (0, 0, 255),
    3,
)

现在我们将在循环之外编写一些代码。首先,我们将编写输出图像以保存输出,然后显示 F1,即应用轮廓后的结果。

在下一行中,我们正在读取变量 F2 中的新帧,在读取新帧之前,我们将 F2 的值分配给 F1。这样,我们正在阅读并找到两个框架之间的差异。

OP.write(IMG)
cv2.imshow("feed", F1)
F1 = F2
ret, F2 = CAP.read()

完整的源代码:

import cv2
import numpy as np

CAP = cv2.VideoCapture("input.avi")
FR_W = int(CAP.get(cv2.CAP_PROP_FRAME_WIDTH))

FR_H = int(CAP.get(cv2.CAP_PROP_FRAME_HEIGHT))

FRC = cv2.VideoWriter_fourcc("X", "V", "I", "D")

OP = cv2.VideoWriter("output.avi", FRC, 5.0, (1280, 720))

ret, F1 = CAP.read()
ret, F2 = CAP.read()
print(F1.shape)
while CAP.isOpened():
    if ret == False:
        print(ret)
        break
    DF = cv2.absdiff(F1, F2)
    Gray_Scale = cv2.cvtColor(DF, cv2.COLOR_BGR2GRAY)
    BL = cv2.GaussianBlur(Gray_Scale, (5, 5), 0)
    _, thresh = cv2.threshold(BL, 20, 255, cv2.THRESH_BINARY)
    DL = cv2.dilate(thresh, None, iterations=3)
    CTS, _ = cv2.findContours(DL, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for CT in CTS:
        (x, y, w, h) = cv2.boundingRect(CT)

        if cv2.contourArea(CT) < 900:
            continue
        cv2.rectangle(F1, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(
            F1,
            "Status: {}".format("Movement"),
            (10, 20),
            cv2.FONT_HERSHEY_SIMPLEX,
            1,
            (0, 0, 255),
            3,
        )

    IMG = cv2.resize(F1, (1280, 720))
    OP.write(IMG)
    cv2.imshow("feed", F1)
    F1 = F2
    ret, F2 = CAP.read()

    if cv2.waitKey(40) == 27:
        break

cv2.destroyAllWindows()
CAP.release()
OP.release()

我们可以看到状态显示移动,因为所有人都在移动。我们还可以查看围绕移动的人绘制的矩形。

OpenCV 跟踪

作者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

相关文章 - Python OpenCV