Exception Handling bei kleinem Script ?

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
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo,
möchte Zeitrafferaufnahmen machen und das Script sollte über längere Zeit lauffähig sein. Ich habe es über mehrere Stunden laufen gehabt und es hat keine Probleme gemacht - bei mir nicht ! Falls die Kamera aus dem USB-Port gezogen wird, wirft Opencv eine Fehlermeldung (VIDIOC_DQBUF: No such device), doch diese kann ich nicht abfangen und das Programm läuft weiter.

Code: Alles auswählen

#! /usr/bin/env python
# -*- coding: utf-8
import time
from datetime import timedelta, datetime
import cv2

stop_time = datetime.now() + timedelta(minutes=10)
cam = cv2.VideoCapture(-1)

if cam.isOpened():
    writer = cv2.VideoWriter("out.avi", 4, 24, (int(cam.get(3)), 
        int(cam.get(4))))
    try:
        while datetime.now() < stop_time:
            time.sleep(1)
            writer.write(cam.read()[1])
    except KeyboardInterrupt:
        print "capture stopped"
    else:
        print "capture finished"
    finally:
        cam.release()
        writer.release()
else:
    print "no cam"
Gruß Frank
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@kaytec
Du behandelst den Fehler ja auch nicht, wie sollte er da abgefangen werden?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Welchen Fehler? Beziehungsweise wie behandeln wenn das gar keine Ausnahme auslöst‽

@kaytec: Wenn OpenCV beim abziehen der Kamera beziehungsweise beim verwenden einer nicht mehr vorhandenen Kamera keine Ausnahme auslöst, dann kann man die auch nicht behandeln. Was passiert denn wenn das Programm weiterläuft? Was wird dann aufgenommen? Kann man eventuell anhand der Rückgabewerte erkennen dass da etwas nicht mehr so läuft wie es sollte?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Was genau gibt den cam.read() zurück wenn keine Kamera mehr existiert?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack
Ich habe
kaytec hat geschrieben:... wirft Opencv eine Fehlermeldung (VIDIOC_DQBUF: No such device), ...
so verstanden, als würde im besagten Fall eine exception stattfinden, die dann innerhalb der Schleife behandelt werden könnte...

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Dann würde aber zumindest der gezeigte Quelltext nicht mehr einfach wie beschrieben weiterlaufen, denn dort wird ja keine Ausnahme ausser `KeyboardInterrupt` behandelt. Und ich gehe mal davon aus, dass *das* nicht die Ausnahme ist die OpenCV auslöst wenn man die Kamera abzieht. :-)
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack
Ach so...
kaytec hat geschrieben:... und das Programm läuft weiter.
@kaytec
Hab' mal in der Dokumentation geschaut. Dort steht u. a. zur `read` Methode:
If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer.
Könnte man damit nicht, wie DasIch ja schon vermutet, was anfangen?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo,
Es müsste doch eigentlich

Code: Alles auswählen

if cam.isOpened():
reagieren, da die Kamera nicht mehr geöffnet ist ? Mit "cv2.VideoWriter.isOpened() → retval" ist auch keine Abfrage möglich, da es kein "False" hergibt. "cv2.VideoCapture.read([image]) → retval, image" ergibt auch kein "False". Wollte einen raspberrypi nehmen und Pflanzenwachstum im Zeitraffer beobachten, doch bei über hundert Grundschülern werden einige dumme Gedanken bekommen. Hätte die Aufnahme mit einer LED angezeigt und bei Abbruch wäre die aus gewesen. Meinen eigenen Rechner würde ich nicht über einige Tage in der Einrichtung lassen und eigene Rechner sind nicht vorhanden. Wäre der raspi defekt oder verschwunden, dann hätte es mich nur 40 € gekostet.

Gruß Frank
BlackJack

@kaytec: Wie sollte denn das ``if`` ”reagieren”? Das wird einmal ausgeführt während die Kamera ja noch eingesteckt ist.

Zu Testen ob der Writer offen ist macht keinen Sinn weil die Datei in die das Video geschrieben wird nichts mit der Kamera zu tun hat. Das wird erst `False` wenn der Writer geschlossen wurde.

Wären wir also wieder bei der Frage was der `read()`-Aufruf denn nun liefert wenn die Kamera abgezogen wurde. `True` und was noch?
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo BlackJack,
True und der letzte Frame. Die Frames vergleichen wird bei einer Pflanzenwuchsaufnahme problematisch werden.

Gruß Frank
BlackJack

@kaytec: Wirklich? Liefert die Kamera auch bei sich nicht veränderndem Motiv 100% gleiche Werte? Kein Rauschen beim Sensor?

Sagt ``dmesg`` auf der Kommandozeile denn etwas wenn man die Kamera abgezohen hat? Das System sollte das ja mitbekommen, also könnte man vielleicht darauf reagieren.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Rauscht der Sensor - keine Ahnung davon. Falls sie wirklich immer unterschiedlich sind, dann würde es mit einem Vergleich ja funktionieren.

Ausgabe von dmesg:

Code: Alles auswählen

[71489.484289] usb 2-1.2: Product: USB2.0 UVC PC Camera
[71489.484292] usb 2-1.2: Manufacturer: GenesysLogic Technology Co., Ltd.
[71489.529397] uvcvideo: Found UVC 1.00 device USB2.0 UVC PC Camera (05e3:0510)
[71489.573393] input: USB2.0 UVC PC Camera as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/input/input52
[71496.716470] uvcvideo: Failed to query (GET_DEF) UVC control 4 on unit 1: -32 (exp. 4).
[71516.488929] uvcvideo: Failed to query (GET_DEF) UVC control 4 on unit 1: -32 (exp. 4).


[71489.484289] usb 2-1.2: Product: USB2.0 UVC PC Camera
[71489.484292] usb 2-1.2: Manufacturer: GenesysLogic Technology Co., Ltd.
[71489.529397] uvcvideo: Found UVC 1.00 device USB2.0 UVC PC Camera (05e3:0510)
[71489.573393] input: USB2.0 UVC PC Camera as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/input/input52
[71496.716470] uvcvideo: Failed to query (GET_DEF) UVC control 4 on unit 1: -32 (exp. 4).
[71516.488929] uvcvideo: Failed to query (GET_DEF) UVC control 4 on unit 1: -32 (exp. 4).
[71660.542277] usb 2-1.2: USB disconnect, device number 27
Danke für deine Hilfe
BlackJack

@kaytec: Ich würde zuerst testen ob das Rauschen der Kamerahardware ausreicht um zu erkennen das die Bilder nicht mehr ”echt” sind. Wenn das nicht ausreicht, dann kannst Du Dich mit dem `pyudev`-Modul beschäftigen um die USB-Kamera zu ”überwachen”.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo BlackJack,

vergleiche die frames und auch bei völliger Dunkelheit scheinen die Arrays unterschiedlich zu sein.

Code: Alles auswählen

import time
from datetime import timedelta, datetime
import numpy as np
import cv2
 
stop_time = datetime.now() + timedelta(minutes=1)
cam = cv2.VideoCapture(-1)
writer = cv2.VideoWriter("out.avi", 4, 24, (int(cam.get(3)),
        int(cam.get(4))))
old_frame = []
no_cam = False
if cam.isOpened():
    try:
        while datetime.now() < stop_time:
            time.sleep(1)
            new_frame = cam.read()[1]
            if np.array_equal(old_frame, new_frame):
                no_cam = True
                break
            writer.write(new_frame)
            old_frame = new_frame
    except KeyboardInterrupt:
        print "capture stopped"
    else:
        if no_cam:
            print "cam disconnect"
        else:
            print "capture finished"
    finally:
        cam.release()
        writer.release()
else:
    print "no cam"
Gruß Frank
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@kaytec: jetzt kann man das noch mit Exceptions machen:

Code: Alles auswählen

    try:
        while datetime.now() < stop_time:
            time.sleep(1)
            new_frame = cam.read()[1]
            if np.array_equal(old_frame, new_frame):
                raise RuntimeError("cam disconnected")
            writer.write(new_frame)
            old_frame = new_frame
    except KeyboardInterrupt:
        print "capture stopped"
    except RuntimeError as error:
        print error
    else:
        print "capture finished"
    finally:
        cam.release()
        writer.release()
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo Sirius3,

ist natürlich viel schöner - ich bin halt kein Programmiere und habe nicht über alle Möglichkeiten den Überblick - bin "Bastelprogrammierer".

Vielen Dank und Gruß
Antworten