@bachatero18: Bitte ``global`` sofort wieder vergessen. Alles was eine Funktion oder Methode ausser Konstanten benötigt, wird als Argument(e) übergeben.
Damit fallen dann die Zuweisungen an `w` und `top_level` weg, wobei `w` auch ein sehr schlechter Name ist.
Dann ist die Zuweisung an `root` unsinnig weil Du nun das gleiche Objekt in der Funktion als `root` und `top` hast, und auch noch beide Namen verwendest. Warum? Was ist das Entscheidungskriterium mal den einen und mal den anderen Namen für das *selbe* Objekt im *selben* Namensraum zu verwenden?
Die Argumente `gui`, `args`, und `kwargs` werden nicht verwendet.
`Kamera_ID` ist falsch geschrieben. Entweder ist das eine Konstante, dann KOMPLETT_GROSS, oder es ist eine variable, dann klein_mit_unterstrichen und dann muss das auch als Argument übergeben werden.
Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. `cap` hat als Wort eine Bedeutung („Kappe“), könnte aber beispielsweise auch eine Abkürzung für `capability` sein.
`label_cam` ist falsch herum wenn man nicht Yoda ist.
Funktionen sollte man in der Regel nicht verschachteln, solange die nicht sehr trivial sind oder man die tatsächlich für ein Closure *braucht*.
Mit den mindestens 50 Millisekunden zwischen den `show_frame()`-Aufrufen darf die Kamera maximal 20 Bilder pro Sekunde liefern, sonst gibt's Stau. Wobei man die Aufruffrequenz besser deutlich niedriger ansetzt als die Bildwiederholrate der Kamera, zum Beispiel halb so gross wie nötig. Der `read()`-Aufruf blockiert dann ja entsprechend bis das nächste Bild dann tatsächlich zur Verfügung steht. Also entweder bei `after()` den Wert für die Wartezeit entsprechend der gelieferten Bildrate anpassen, oder die Bildrate an den Wert bei `after()` anpassen. Oder eine Kombination. Also zum Beispiel bei `after()` etwas zwischen 8 und 10 um bei 60 Bildern pro Sekunde auf der sicheren Seite zu sein.
Man sollte das erste Argument im Tupel das `read()` zurückgibt nicht einfach ignorieren. Das geht solange gut bis das mal nicht gut geht und der Code auf die Nase fällt weil `frame` nichts ethält.
`hsv` ist ein verdammt schlechter Name für Bilddaten die gar nicht im HSV- sondern im RGB-Format sind.
Ungetestet:
Code: Alles auswählen
def show_frame(video, width, height, camera_image_label):
is_ok, frame = video.read()
if is_ok:
image = ImageTk.PhotoImage(
image=Image.fromarray(
cv2.cvtColor(
cv2.resize(frame, (width * 1, height * 1)),
cv2.COLOR_BGR2RGB,
)
)
)
camera_image_label.image = image
camera_image_label.configure(image=image)
camera_image_label.after(
10, show_frame, video, width, height, camera_image_label
)
def init(window, kamera_id, width, height):
window.protocol("WM_DELETE_WINDOW", destroy_window)
window.state("zoomed")
video = cv2.VideoCapture(kamera_id)
video.set(cv2.CAP_PROP_FRAME_WIDTH, width)
video.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
camera_image_label = tk.Label(window)
camera_image_label.pack()
show_frame(video, width, height, camera_image_label)