OpenCV-Verfolgung

Salman Mehmood 15 Februar 2024
OpenCV-Verfolgung

Diese Demonstration zielt darauf ab, zu lernen, wie man ein sehr einfaches und einfaches Bewegungserkennungs- und Verfolgungssystem mit Python und OpenCV erstellt. Wir erreichen, dass jede Person mit einem rechteckigen Begrenzungsrahmen am Ende dieses Artikels verfolgt wird.

Erstellen Sie ein Bewegungserkennungs- und Verfolgungssystem mit Python und OpenCV

Zuerst müssen wir zwei Frames aus der Instanz CAP lesen.

ret, F1 = CAP.read()

In ähnlicher Weise werden wir den zweiten Rahmen lesen.

ret, F2 = CAP.read()

Jetzt deklarieren wir eine Variable namens DF und verwenden die Funktion absdiff(). Das absdiff() hilft, den absoluten Unterschied zwischen Frames zu finden, das erste F1 und das zweite F2.

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

Wandeln Sie diese Differenz mit der Methode cvtColor() in einen Graustufenmodus um. Der erste Parameter ist DF.

Das zweite Argument ist COLOR_BGR2GRAY, das hilft, die Rahmenfarbe BGR in den Graustufenmodus zu konvertieren; Warum finden wir den Graustufenmodus heraus?

Da wir die Kontur in späteren Phasen finden werden, ist es einfacher, die Konturen im Graustufenmodus zu finden als im farbigen Modus.

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

Sobald wir den Graustufenmodus haben, müssen wir unseren Graustufenrahmen mit der Methode GaussianBlur() verwischen. Es braucht ein paar Parameter; der erste ist Gray_Scale, der zweite Parameter ist die Kernelgrösse 5x5 und der dritte Parameter ist der Sigma X-Wert.

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

Wir müssen den Schwellenwert mit der Methode threshold() bestimmen. Es gibt zwei Objekte zurück; wir definieren _, weil wir die erste Variable nicht brauchen und dann ist die zweite Variable thresh.

Im ersten Parameter übergeben wir unser verschwommenes Bild als Quelle, und der zweite Parameter ist der Schwellenwert von 20. Der maximale Schwellenwert beträgt 255; der Typ ist THRESH_BINARY.

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

Wir müssen das Schwellenbild erweitern, um alle Löcher zu füllen; Dies wird uns helfen, bessere Konturen zu finden. Die Methode dilate() benötigt einige Parameter; Der erste Parameter ist der definierte Schwellenwert und der zweite Parameter die Kernelgröße, aber wir übergeben sie an None.

Das dritte Argument ist die Anzahl der Iterationen als 3. Wenn es nicht funktioniert, können Sie die Anzahl der Iterationen erhöhen oder verringern.

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

Im nächsten Schritt werden wir die Kontur herausfinden, und die Methode findContours() liefert uns zwei Ergebnisse; Das eine sind die Konturen und das andere die Hierarchie, aber wir werden das zweite Ergebnis nicht verwenden. Wir werden die Konturen auf dem erweiterten Bild finden.

Wir übergeben also ein dilatiertes Bild im ersten Parameter, und der nächste ist der am häufigsten verwendete RETR_TREE-Modus. Der nächste Parameter ist die Methode CHAIN_APPROX_SIMPLE.

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

Im nächsten Schritt wollen wir die Rechtecke zeichnen, also iterieren wir mit der for-Schleife über alle Konturen. Das CTS ist eine Liste, und wir iterieren über diese Liste, also besteht der erste Schritt darin, alle Koordinaten der Konturen mit der Methode boundingRect() zu speichern.

Im nächsten Schritt ermitteln wir den Konturbereich, und wenn dieser Bereich kleiner als ein bestimmter Wert ist, zeichnen wir kein Rechteck. Innerhalb der for-Schleife definieren wir, dass wir die Iteration fortsetzen, wenn der Konturbereich kleiner als 700 ist; Zeichnen Sie andernfalls das Rechteck.

Um das Rechteck zu zeichnen, müssen wir die Methode cv2.rectangle() verwenden, und das erste Argument hier ist die Quelle, die F1 sein wird; der zweite Parameter ist Punkt 1 (x,y). Der dritte Parameter ist Punkt 2, der nächste Parameter ist ein Tupel als Farbwert und der nächste Parameter ist die Dicke.

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)

Wir werden etwas Text auf dem Bild platzieren, wenn eine Bewegung beobachtet wird. Wir verwenden die Methode cv2.putText(); Diese Methode nimmt F1, der zweite ist der Text, und der nächste Argumentparameter ist der Ursprung, an dem wir diesen Text platzieren möchten.

Der nächste Parameter ist die Schriftart FONT_HERSHEY_SIMPLEX; Der nächste Parameter ist die Schriftskalierung. Das nächste ist die Farbe der Schriftart; dann ist der letzte Parameter die Dicke des Textes.

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

Jetzt schreiben wir etwas Code außerhalb der Schleife. Zuerst schreiben wir Ausgabebilder, um die Ausgabe zu speichern, und zeigen dann F1 an, das Ergebnis nach dem Anwenden der Kontur.

In der nächsten Zeile lesen wir den neuen Frame in der Variablen F2 und weisen vor dem Lesen des neuen Frames dem F1 den Wert von F2 zu. Auf diese Weise lesen und finden wir den Unterschied zwischen den beiden Rahmen.

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

Vollständiger Quellcode:

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()

Wir können sehen, dass der Status Bewegung anzeigt, weil sich alle Menschen bewegen. Wir können auch Rechtecke betrachten, die um die sich bewegende Person gezogen werden.

OpenCV-Verfolgung

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

Verwandter Artikel - Python OpenCV