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.
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.
Bitte bereiten Sie die folgenden Punkte vor.
Das Bild des ausgeschnittenen Balls ist wie folgt. Unten ist ein Beispiel.
Befolgen Sie die nachstehenden Schritte, um zu verfolgen.
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:
Erkennt Bälle in dem Bereich, der vom roten Rahmen umgeben ist. Dieses Bild wird in ein Schwarzweißbild umgewandelt.
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.
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.
Auf diese Weise kann der Ball erkannt werden, ohne von der Helligkeit oder dem Hintergrund beeinflusst zu werden.
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)
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.
Es gab eine Möglichkeit, Rauschen und Ausreißer zu korrigieren, aber ich habe es vergessen, also erinnere ich mich wieder daran.
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