Verfolgen Sie Baseballbälle mit Python + OpenCV

Als ich die OpenCV-Site zum ersten Mal seit einiger Zeit wieder sah, war sie neu und ich berührte sie für einen Moment.

https://opencv.org/

Ich habe vor langer Zeit Baseballbälle in Java verfolgt, also habe ich es diesmal in Python versucht. Tracking ist eine Kombination aus Hintergrundunterschieden und Vorlagenabgleich.

Umgebung

Die Umgebung ist wie folgt.

Ich schaffe eine Umgebung mit "venv". Es ist egal, ob es nicht "venv" ist.

$ python -m venv pythonOpevCV
$ cd pythonOpenCV
$ Script\activate
$ python -m pip install --upgrade pip
$ pip install opencv-python
Successfully installed numpy-1.18.2 opencv-python-4.2.0.34

numpy wird ebenfalls installiert.

Was vorzubereiten?

Bitte bereiten Sie die folgenden Punkte vor.

Das Bild des ausgeschnittenen Balls ist wie folgt. Unten ist ein Beispiel.

template.jpeg

Verfahren

Befolgen Sie die nachstehenden Schritte, um zu verfolgen.

  1. Speichern Sie als Bild für jedes Bild des Videos
  2. Graustufenrahmenbild und Vorlagenbild
  3. Rahmenbild und Vorlagenbild binarisieren
  4. Machen Sie einen Hintergrundunterschied zwischen dem vorherigen und dem nächsten Einzelbild
  5. Führen Sie einen Vorlagenabgleich mit dem Bild durch, der sich aus dem Hintergrundunterschied ergibt
  6. Zeichnen Sie die Tracking-Ergebnisse

Selbst wenn der Vorlagenabgleich plötzlich für das ursprüngliche Rahmenbild durchgeführt wird, werden Wolken und Gebäude im Hintergrund fälschlicherweise als Kugeln erkannt, und die Genauigkeit ist nicht gut. Daher Graustufen → Binärisierung, um ein Schwarzweißbild zu erstellen. Wenn Sie im Schwarzweißbildzustand einen Hintergrundunterschied zwischen dem vorherigen und dem nächsten Bild machen, bewegen sich die Wolken und der Hintergrund in etwa 0,1 Sekunden kaum, sodass Sie den sich bewegenden Ball klar erkennen können.

Das Graustufenbild sieht folgendermaßen aus:

gray.jpeg

Erkennt Bälle in dem Bereich, der vom roten Rahmen umgeben ist. Dieses Bild wird in ein Schwarzweißbild umgewandelt.

binary.jpeg

Der Ball kann in Weiß erkannt werden, aber nur der Ball kann nicht erkannt werden, da Hintergrund und Ball gleich weiß sind. Hier ist der Hintergrundunterschied zwischen dem vorherigen und dem nächsten Einzelbild wie folgt.

sub.jpeg

Der weiße Hintergrund funktioniert nicht und wird nicht durch den Hintergrundunterschied erkannt. Nur der Ball und andere Geräusche werden in Weiß erkannt. In diesem Zustand wird der Vorlagenabgleich mit dem binärisierten Bild des folgenden Vorlagenbilds durchgeführt.

templatebi.jpeg

Auf diese Weise kann der Ball erkannt werden, ohne von der Helligkeit oder dem Hintergrund beeinflusst zu werden.

Quellcode

Der Quellcode lautet wie folgt. Platzieren Sie das Zielvideo in "VIDEOPATH" und das Vorlagenbild in "TEMPLATEPATH".

main.py


import glob
import re
import cv2


VIDEOPATH = "media/video/video.mp4"
IMAGEPATH = "media/image/"
TEMPLATEPATH = "template.jpeg "


def save_frames(video_path, image_dir):
    """
Extrahieren Sie Einzelbilder aus Videos
    """
    cap = cv2.VideoCapture(video_path)
    digit = len(str(int(cap.get(cv2.CAP_PROP_FRAME_COUNT))))
    n = 0
    while True:
        ret, frame = cap.read()
        if ret:
            cv2.imwrite("{}original/frame_{}.{}".format(IMAGEPATH, n, "jpeg"), frame)
            n += 1
        else:
            return


def do_grayscale(image_path):
    """
Graustufenbild
    """
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    save_image(image_path, "gray", gray)


def do_binarization(image_path):
    """
Binarisieren Sie das Bild
    """
    img = cv2.imread(image_path)
    ret, img_thresh = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
    save_image(image_path, "binary", img_thresh)


def do_backgroundsub():
    """
Hintergrundunterschied machen
    """
    img_list = glob.glob(IMAGEPATH + "binary/frame*.jpeg ")
    num = lambda val: int(re.sub("\D","",val))
    sorted(img_list,key=(num))
    source = img_list[0]
    for path in img_list:
        diff = cv2.absdiff(cv2.imread(source),cv2.imread(path))
        source = path
        save_image(path, "bgsub", diff)


def do_template_matching():
    """
Führen Sie einen Vorlagenabgleich zwischen Vorlagenbild und Rahmenbild durch
    """
    template_img = cv2.imread(IMAGEPATH + "binary/" + TEMPLATEPATH)
    img_list = glob.glob(IMAGEPATH + "bgsub/frame*.jpeg ")
    num = lambda val: int(re.sub("\D","",val))
    sorted(img_list,key=(num))
    location_list = []
    for path in img_list:
        result = cv2.matchTemplate(cv2.imread(path), template_img, cv2.TM_CCOEFF)
        minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result)
        location_list.append(maxLoc)
    return location_list

def draw_rectangle(location_list):
    """
Zeichnen Sie das passende Ergebnis auf das Bild
    """
    source = cv2.imread(IMAGEPATH + "original/frame_0.jpeg ")
    cv2.imwrite(IMAGEPATH + "result.jpeg ",source)
    source = cv2.imread(IMAGEPATH + "result.jpeg ")
    for loc in location_list:
        lx, ly, rx, ry = loc[0] - 10, loc[1] - 10, loc[0] + 10, loc[1] + 10
        img = cv2.rectangle(source, (lx, ly), (rx, ry), (0, 255, 0), 3)
        cv2.imwrite(IMAGEPATH + "result.jpeg ",img)

def save_image(img_path, dir, img):
    """
Bild speichern
    img_path :Bildpfad
    dir :Verzeichnisname
    img :Bilddaten
    """
    file_name = img_path.replace("\\","/").split(".")[0].split("/")[-1]
    cv2.imwrite("{}{}/{}.{}".format(IMAGEPATH, dir, file_name,"jpeg"), img)


if __name__=="__main__":
    #① Teilen Sie das Video in Frames
    save_frames(VIDEOPATH,IMAGEPATH)
    #(2) Graustufen des Vorlagenbilds und des Rahmenbilds
    do_grayscale(IMAGEPATH + TEMPLATEPATH)
    for path in glob.glob(IMAGEPATH + "original/*.jpeg "):
        do_grayscale(path)
    #③ Binarisierung von Vorlagenbild und Rahmenbild
    for path in glob.glob(IMAGEPATH + "gray/*.jpeg "):
        do_binarization(path)
    #④ Hintergrunddifferenz durchführen
    do_backgroundsub()
    #⑤ Führen Sie einen Vorlagenabgleich durch
    location_list = do_template_matching()
    #⑥ Projizieren Sie die übereinstimmenden Koordinaten
    draw_rectangle(location_list)

Ergebnis

Ich habe versucht, den Ball im Wurfvideo zu erkennen. Obwohl es im Allgemeinen erkannt werden kann, erkennt es auch andere Teile als die Flugbahn des Balls.

result.jpeg

Es gab eine Möglichkeit, Rauschen und Ausreißer zu korrigieren, aber ich habe es vergessen, also erinnere ich mich wieder daran.

Zusammenfassung

Die Verfolgung von Baseballbällen wurde unter Verwendung von Hintergrundunterschieden und Vorlagenabgleich mit Python + OpenCV durchgeführt. Wenn Sie "YOLO" verwenden, können Sie den Baseballball anscheinend anhand des Bildes erkennen. Daher möchte ich auch diesen Bereich ausprobieren.

Recommended Posts

Verfolgen Sie Baseballbälle mit Python + OpenCV
Binarisierung mit OpenCV / Python
"Apple-Verarbeitung" mit OpenCV3 + Python3
Bildbearbeitung mit Python OpenCV
Kameraerfassung mit Python + OpenCV
[Python] Verwenden von OpenCV mit Python (Basic)
Gesichtserkennung mit Python + OpenCV
Verwenden von OpenCV mit Python @Mac
Leuchtendes Leben mit Python und OpenCV
[Python] Verwenden von OpenCV mit Python (Bildfilterung)
Neuronales Netzwerk mit OpenCV 3 und Python 3
[Python] Verwenden von OpenCV mit Python (Bildtransformation)
[Python] Verwenden von OpenCV mit Python (Kantenerkennung)
Einfache Python + OpenCV-Programmierung mit Canopy
Schneiden Sie das Gesicht mit Python + OpenCV aus
Gesichtserkennung mit Kamera mit opencv3 + python2.7
Laden Sie das GIF-Bild mit Python + OpenCV
Finden Sie Bildähnlichkeit mit Python + OpenCV
Graphbasierte Segmentierung mit Python + OpenCV
Zeichnen Sie einen Pfeil (Vektor) mit opencv / python
Grundlegendes Studium von OpenCV mit Python
Gesichtserkennung mit Python + OpenCV (invariante Rotation)
Speichern Sie Videos Frame für Frame mit Python OpenCV
Bilder mit Pupil, Python und OpenCV aufnehmen
Ich habe versucht, mit Python + opencv nicht realistisch zu rendern
Bildverarbeitung mit Python & OpenCV [Tonkurve]
Bildaufnahme von der Kamera mit Python + OpenCV
[python, openCV] base64 Gesichtserkennung in Bildern
Erstellen verschiedener Photoshop-Videos mit Python + OpenCV ③ Erstellen Sie verschiedene Photoshop-Videos
[Python] Bilder mit OpenCV lesen (für Anfänger)
Bis Sie opencv mit Python verwenden können
Leichte Bildverarbeitung mit Python x OpenCV
Glättung kantengespeichert mit Python + OpenCV (BilateralFilter, NLMeansFilter)
FizzBuzz in Python3
Scraping mit Python
Statistik mit Python
Scraping mit Python
Twilio mit Python
In Python integrieren
Spielen Sie mit 2016-Python
AES256 mit Python
Python beginnt mit ()
OpenCV-Beispiele (Python)
Bingo mit Python
Zundokokiyoshi mit Python
[Hinweis] openCV + Python
Verfolgen Sie Python-Programme
Excel mit Python
Mikrocomputer mit Python
Mit Python besetzen
Hallo Welt- und Gesichtserkennung mit OpenCV 4.3 + Python
Ich habe versucht, das Bild mit Python + OpenCV zu "glätten"
Verfolgen Sie Objekte in Ihrem Video mit OpenCV Tracker
Leistungsvergleich des Gesichtsdetektors mit Python + OpenCV
Ich habe versucht, das Bild mit Python + OpenCV zu "differenzieren"
Kantenextraktion mit Python + OpenCV (Sobel-Filter, Laplace-Filter)
So beschneiden Sie ein Bild mit Python + OpenCV
Installieren Sie OpenCV 4.0 und Python 3.7 unter Windows 10 mit Anaconda
Verfolgen Sie grüne Objekte mit Python + Numpy (Partikelfilter)
Stellen Sie OpenCV3 in Python3 zur Verfügung, das mit pyenv installiert wurde
Ich habe versucht, das Bild mit Python + OpenCV zu "binarisieren"