Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung | |||
ss18:tracker [2018/08/23 16:52] dclaussner |
ss18:tracker [2018/08/24 18:05] (aktuell) dclaussner |
||
---|---|---|---|
Zeile 34: | Zeile 34: | ||
- Schließen des Tracking-Fensters | - Schließen des Tracking-Fensters | ||
* **openAndConfigureWindow()** | * **openAndConfigureWindow()** | ||
- | - Öffnet und konfiguriert ein OpenCV-Fenster | + | * Öffnet und konfiguriert ein OpenCV-Fenster |
+ | \\ | ||
==== multi_tracker.py ==== | ==== multi_tracker.py ==== | ||
* **addInitialObjects(data, frame)** | * **addInitialObjects(data, frame)** | ||
- Annahme der übergebenen Puck-Objekte in Form einer vollständigen Kopie | - Annahme der übergebenen Puck-Objekte in Form einer vollständigen Kopie | ||
- Vollständige Kopie des derzeitigen Bilds, auf der die Markierungen angezeigt werden | - Vollständige Kopie des derzeitigen Bilds, auf der die Markierungen angezeigt werden | ||
- | - | + | - Initialisierung der Tracker |
+ | - Initialer Tracking-Versuch, um sicherzustellen, dass der Tracker den Puck verfolgen kann | ||
+ | - Anzeige der Indizes der Pucks auf dem Frame | ||
+ | - Rückgabe der Frame-Kopie und Positionsdaten an tracker.setup() | ||
+ | * **trackObjects(frame)** | ||
+ | - Vollständige Kopie des derzeitigen Bilds, auf der die Markierungen angezeigt werden | ||
+ | - Falls aktiv, Aufruf von trackObjectsThreaded(), andernfalls sequentieller Aufruf der Tracking-Routine der Pucks und Speicherung der Daten | ||
+ | - Überprüfung der Anzahl an erfolgreich verfolgten Pucks | ||
+ | - Wiederherstellungsversuch fehlender Pucks durch Aufruf von updateBoxesWithCascade() | ||
+ | - Darstellung und Speicherung wiedergefundener Pucks | ||
+ | - Rückgabe der Frame-Kopie und Positionsdaten and tracker.run() | ||
+ | * **trackObjectsThreaded(frame, frameCopy, positions)** | ||
+ | - Erzeugung eines Lock-Objekts zur Synchronisierung der Threads beim Zugriff auf gemeinsame Resourcen (frameCopy, positions) | ||
+ | - Initialisierung, Start und Speicherung der WorkerThreads | ||
+ | - Blockierung des Main-Threads, bis alle WorkerThreads beendet wurden | ||
+ | * **updateBoxesWithCascade(frame, positions, frameCopy)** | ||
+ | - Suche der Pucks mithilfe der HAAR-Kaskade durch Aufruf von cascade.findPucks() | ||
+ | - Entfernung aller Boxen, die Pucks enthalten, deren Tracker noch zuverlässig arbeiten | ||
+ | - Vergößerung der Boxen, um die Chancen der Zuordnung zu der letzten bekannten Position des jeweiligen Pucks zu erhöhen | ||
+ | - Zuordnung der Boxen zu ihren Pucks und Aktualisierung der Daten des jeweiligen Pucks | ||
+ | - Rückgabe der wiedergefundenen Pucks an trackObjects() | ||
+ | * **notifyPuckHardFail()** | ||
+ | * Dekrementierung der Anzahl zuverlässig verfolgbarer Pucks | ||
+ | * **cleanupMultiTracker()** | ||
+ | * Löschen der Puck-Objekte und Zurücksetzen der Puck-Anzahl, um eine erneute Verwendung des Trackers ohne Programmneustart zu ermöglichen | ||
+ | \\ | ||
+ | ==== worker_thread.py ==== | ||
+ | * **%%__%%init%%__%%(self, puck, frame, frameCopy, posList, lock)** | ||
+ | * Speicherung der übergebenen Daten | ||
+ | * **run(self)** | ||
+ | - Aufruf der Tracking-Routine des jeweiligen Pucks | ||
+ | - Aktivierung des Thread-Lock, um Kollisionen beim Zugriff auf die Liste hinter der Referenz self.posList zu verhindern | ||
+ | - Speicherung des Tracking-Ergebniss in self.posList | ||
+ | - Freigabe des Thread-Lock | ||
+ | \\ | ||
+ | ==== puck_kcf.py ==== | ||
+ | * **%%__%%init%%__%%(self, identifier, track_window)** | ||
+ | * Speicherung der übergebenen Daten | ||
+ | * **setupValues(self, frame)** | ||
+ | - Erzeugung des KCF-Tracker-Objekts | ||
+ | - Initialisierung des KCF-Trackers mithilfe der Box des entsprechenden Pucks und dem übergebenen Frame | ||
+ | * **track(self, frame, frameCopy, threadLock = None)** | ||
+ | - Aufruf des Tracking-Algorithmus | ||
+ | - Falls erfolgreich, Darstellung des Tracking-Ergebnisses, falls notwendig unter Benutzung des Thread-Lokc | ||
+ | - Bei Fehlschlag, Markierung des Pucks als nicht verfolgbar und Inkrementierung eines Frame-Zählers, wie lange der Puck nicht verfolgt werden konnte | ||
+ | - Ist der Puck mahr als 5 Frames nicht verfolgbar, wird die letzte bekannte Position als nutzlos eingestuft und die Verfolgung dieses Pucks durch Markierung als nicht nutzbar und den Aufruf von multi_tracker.notifyPuckHardFail() aufgegeben | ||
+ | - Rückgabe der in vier Eckkoordinaten umgerechneten Positionsdaten | ||
+ | * **checkBoxRelation(self, box)** | ||
+ | * Überprüft, ob sich die letzte bekannte Position dieses Pucks in der übergebenen Box befindet | ||
+ | * **notifyRecovered(self, newBox, frame)** | ||
+ | * Speicherung der neuen, mithilfe der Kaskade wiedergefundenen, Box dieses Pucks und Zurücksetzung der Fehlschlag-Markierungen und Zähler | ||
+ | * **drawMarkerOnFrame(self, frameCopy)** | ||
+ | * Darstellung der derzeitigen Position dieses Pucks auf dem übergebenen Frame | ||
+ | * **printIndizes(self, frameCopy)** | ||
+ | * Darstellung des Index dieses Pucks auf dem übergebenen Frame auf der Position dieses Pucks | ||
+ | \\ | ||
+ | ==== cascade.py ==== | ||
+ | * **findPucksInitial(cascadeFile, frame)** | ||
+ | - Laden der HAAR-Kaskade aus dem übergebenen Datei cascadeFile | ||
+ | - Aufruf von findPucks() zur Lokalisierung der Pucks auf dem übergebenen Frame | ||
+ | * **findPucks(frame)** | ||
+ | - Konvertierung des übergebenen Frames in Graustufen | ||
+ | - Lokalisierung der Pucks auf dem Graustufen-Bild mithilfe der zuvor geladenen HAAR-Kaskade | ||
+ | - Konvertierung der Daten aus der Kaskade in Tuple | ||
+ | - Rückgabe der Ergebnisse als Liste von Tuplen | ||
+ | \\ | ||
+ | ==== utils.py ==== | ||
+ | * **getCoordsFromXYWH(data)** | ||
+ | * Konvertierung der übergebenen Daten (Koordinaten der linken oberen Ecke und Breite und Höhe eines Rechtecks) in eine Liste mit den Koordinaten aller vier Ecken im Uhrzeigersinn, angefangen mit der oberen linken Ecke | ||
+ | * **doesBox1ContainBox2(box1, box2)** | ||
+ | * Überprüft, ob sich box2 vollständig in box1 befindet | ||
+ | * **doesBoxContainCoords(box, coords)** | ||
+ | * Überprüft, ob sich die Box coords in Koordinatenform vollständig in der Box box (obere linke Ecke und Breite und Höhe) befindet | ||
+ | * **checkSizeOK(box)** | ||
+ | * Überprüft, ob die übergebene Box mindestens so groß, wie die Boxen, die an den Tracker übergeben werden (festgelegt durch dotSize) und kleiner als die maximale Boxgröße boxSizeMax ist | ||
+ | * **filterDuplicates(boxes)** | ||
+ | * Filtert alle Boxen aus der übergebenen Liste boxes heraus, die sich vollständig in einer anderen Box in dieser Liste befinden | ||
+ | * **shrinkBox(box)** | ||
+ | * Verkleinert die übergebene Box auf eine einheitliche Größe für den Tracker (festgelegt durch dotSize) | ||
+ | * **enlargeBox(box, size)** | ||
+ | * Vergrößert die übergebene Box auf die übergebene Größe | ||
+ | * **millis()** | ||
+ | * Gibt die derzeitige Systemzeit in Millisekunden als Integer zurück | ||
+ | * **clockStringFromSecs(secs)** | ||
+ | * Konvertiert die übergebene Zeit in Sekunden in einen Zeit-String der Form HH:MM:SS | ||
+ | \\ | ||
+ | \\ | ||
+ | ---- | ||
+ | Autor: Dennis Claußner |