globale Variablen Opencv?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tschaka81
User
Beiträge: 31
Registriert: Donnerstag 24. Januar 2019, 08:15

Hallo,

ich verzweifle gerade an einem simplen Problem und sehe die Lösung nicht. vielleicht kann mir hier jemand weiterhelfen:

Ich habe eine ganz simple Flask app. Vor dem app.run starte ich einen Thread, welcher mir Videodaten generiert.

Code: Alles auswählen


if __name__ == "__main__":
    api_vars = {"qrcode":"", "frame": ""}
    t = Thread(target=gen_frames)
    t.setDaemon(True) 
    t.start()
    while True:
        print(api_vars)    
    app.run(debug=True, host='0.0.0.0', port=5000)
    
Dieser Code klappt und wirft in api_vars meine gesuchten Werte aus.


Jetzt wollte ich den Code in einem Weblink abholen. Dazu habe ich zunächst eine weitere Funktion geschrieben:

Code: Alles auswählen

def gen_frames():
    global api_vars
    pipeline = """libcamerasrc ! video/x-raw, width=640, height=480, framerate=30/1 ! videoconvert ! videoscale ! clockoverlay time-format="%D %H:%M:%S" ! appsink"""
    camera = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
    while True:
        api_vars["qrcode"] = "Hallo"
        api_vars["frame"] = [1,2,3,4]  
        
@app.route('/video_feed')
def video_feed():
    global api_vars
    while True:
        print(api_vars)
        time.sleep(1)        
Das gilt nur als Test. Wenn ich die Zeile camera = auskommentiere, dann klappen die globalen Variablen richtig. Nehme ich die Zeile rein, dann "scheint" meine Zeile mit global wieder weg zu sein?
also kurz:

Code: Alles auswählen

camera => api_vars = {"qrcode":"",  "Hallo" ""}
#camera => api_vars = {"qrcode":"", "frame":  [1,2,3,4]}

Es hilft auch nichts global nach camera zu setzen. Weiß jemand, ob OpenCV irgendwas mit den globalen Variablen anstellt? Wie würdet ihr das Problem angehen?
Sirius3
User
Beiträge: 18225
Registriert: Sonntag 21. Oktober 2012, 17:20

Der ganze Code macht ja so keinen Sinn. `video_feed` liefert gar keine Daten. Mit der Kamera machst Du in Deinem Code auch nichts.
Was Du mit "auskommentieren" meinst, verstehe ich nicht. Wie erkennst Du, dass global nicht funktioniert?
Benutzeravatar
__blackjack__
User
Beiträge: 13930
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tschaka81: Erst einmal sind beide ``global``-Anweisungen überflüssig. Ob die da sind oder nicht, ändert nichts am Verhalten des Programms. Das heisst auch die ``camera = …``-Zeile hat da keinen Einfluss drauf, weil die ``global``-Deklarationen sowieso unsinnig/unnötig sind.

Selbst wenn ``global`` hier etwas bewirken würde, ist es keine gute Idee globale Variablen zu verwenden wo man sie wirklich einfach auch vermeiden könnte. Es wäre beispielsweise kein Problem das Wörterbuch `gen_frames()` als Argument zu übergeben.

Es ist also wahrscheinlich, dass die ``camera = …``-Zeile entweder eine Ausnahme auslöst, oder der Aufruf/das erstellen des Objekts aus irgend einem Grund blockiert, so dass die folgende ``while``-Schleife gar nicht ausgeführt wird.

Die Schleife hat übrigens noch das Problem, dass die *zwei* Änderungen an dem Wörterbuch vornimmt, die nicht atomar sind. Wenn man das also von einem anderen Thread aus verwendet, ist nicht garantiert, dass die beiden Werte auch tatsächlich zusammengehören. Falls das ein Problem ist, müsste man Zugriffe auf das Wörterbuch entsprechend mit einem Lock absichern.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
tschaka81
User
Beiträge: 31
Registriert: Donnerstag 24. Januar 2019, 08:15

Hallo.

wie das mit minimal Beispielen so ist, war dies zu minimalistisch...

Kurs gesprochen: Ich kann die globalen variablen im Programm nutzen, wenn ich die Zeile camera weglasse. Noch viel interessanter ist, dass es auch klappt, wenn ich die Zuweisung weglasse: Sprich nicht:

Code: Alles auswählen

camera = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
sondern

Code: Alles auswählen

cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
Ich habe das Problem jetzt umgeschrieben und mittels Iterator angegangen. Unabhängig davon verstehe ich immer noch nicht, warum die "globale" Variable geblockt wird, wenn ich die Zeile code von opencv einfüge.

Im übrigen: die obigen while Schleifen sind nur als Test gedacht. Bitte keine Logic reininterpretieren.
Benutzeravatar
Dennis89
User
Beiträge: 1504
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

du wirst vermutlich mal den eigentlichen Code zeigen müssen.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten