Kivy - Bilder werden nach löschen weiter angezeigt

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Dudu
User
Beiträge: 13
Registriert: Donnerstag 13. April 2017, 08:30

Liebes Pythonforum,

für meinen Spurhalteassistenten verwende ich einen Raspberry Pi mit Kameramodul V2 und einem Touchdisplay. Die zugehörige GUI habe ich mithilfe der Kivy-Bibliothek geschrieben. Über die Kamera sollen nun bei jedem Durchlauf Bilder aufgenommen werden und anschließend in der GUI dargestellt werden. Das Ganze soll über einen Start-Button eingeleitet und auf dem folgenden Screen über einen Abbruch-Button zurück zum Start-Screen führen.

Soweit so gut. Die Funktionen sind gegeben. Allerdings werden die Bilder nicht aktualisiert. Ich habe bereits versucht die Bilder mit dem Abbruch-Button zu löschen, um zu gewährleisten, dass diese nicht erneut aufgerufen werden können. Faszinierender Weise werden die gelöschten Bilder angezeigt, obwohl diese nicht mehr existieren, und die neu erstellten werden vernachlässigt.

Wie kann das sein? Sind diese Bilder immer noch in einem Zwischenspeicher vorhanden und falls Ja, wie kann ich diesen überschreiben bzw. löschen?

Mit freundlichem Gruß
Dudu
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein interessantes Problem. Ich bin mir ziemlich sicher, dass dein Fehler in der Kalibration des untergaerigen Fluxkompensatoradapters zu suchen ist. Dabei muss man allerdings etwas aufpassen, weil man sich sonst schnell einen veritablen Cache-Miss einfaengt.

Das ist natuerlich alles Unsinn. Aber da du ausser einer schoenen Geschichte nichts vorgelegt hast, dass einem die Beurteilung des Problems erlaubt, kann man auch sonst wenig machen....

Also: Code zeigen, ggf. reduziert auf ein minimales Beispiel (was oft das Problem schon loest) - sonst kann dir hier keiner helfen.
Dudu
User
Beiträge: 13
Registriert: Donnerstag 13. April 2017, 08:30

Danke für die höchst sarkastische Antwort. Zunächst könnte meine Frage bezüglich des Zwischenspeichers bestimmt auch ohne Code gelöst werden. Aber da du so nett gefragt hast, sende ich hier noch einen Teil meines Skriptes:

Hier die zugehörige Klasse, in der Bilder aufgenommen und abgespeichert werden:

Code: Alles auswählen

class Display4(Screen):
    def Aufnahme(self):
        global Freigabe
        Freigabe = True
        if Freigabe == True:
            
            #Bild aufnehmen und abspeichern
            camera = PiCamera()
            camera.start_preview()
            sleep(3)
            camera.capture('/home/pi/Desktop/Bilder/image0.jpg')
                       
            img = Image.open('/home/pi/Desktop/Bilder/image0.jpg')
            global img2
            img2 = img.convert('L')
            img2.save("/home/pi/Desktop/Bilder/image1.jpg")
            camera.stop_preview()
            camera.close()                        
                
            
            display_manager.transition.direction = 'left'
            display_manager.transition.duration = 0.5
            display_manager.current = 'display_2'
        else:
            pass
Nun die Funktion, mit der ich diese nach Abbruch bzw. anschließendem Start aktualisiere

Code: Alles auswählen

 def Bildupdate(self):
        global Freigabe
        if Freigabe == True:
            self.ids.bild1.source = "/home/pi/Desktop/Bilder/image0.jpg"
            self.ids.bild2.source = "/home/pi/Desktop/Bilder/image1.jpg"
In der Abbruchfunktion werden die Bilder gelöscht, bevor diese beim neuen Start wieder erstellt werden.
Wie bereits erwähnt werden dennoch die vorherigen Bilder angezeigt.
Zuletzt geändert von Anonymous am Mittwoch 17. Mai 2017, 14:57, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Dudu: Ein minimales aber lauffähiges Beispiel wäre hilfreich. So dass man das Problem auch nachvollziehen kann. Sonst kann man nur sagen das Du wahrscheinlich irgendwo, irgend etwas nicht richtig machst. Es hat vielleicht sogar etwas mit globalen Variablen die anscheinend so etwas wie einen Sperrmechanismus darstellen sollen (`Freigabe`) zu tun. ``global`` hat in einem sauberen Programm nichts zu suchen, und wenn man schon mit Klassen arbeitet, gibt es dafür eigentlich auch keine Ausrede mehr.

Ein wirklich minimales Beispiel könnte alleine schon darin bestehen, dass Du mal schaust ob Kivy überhaupt ein Bild aktualisiert das den gleichen Dateinamen hat. Vielleicht schaut das beim setzen auch einfach den Dateinamen an, stellt fest, dass das bereits angezeigte Bild den gleichen Namen hat, und lädt deswegen nicht neu.
Dudu
User
Beiträge: 13
Registriert: Donnerstag 13. April 2017, 08:30

@BlackJack: Danke für den Ansatz.
Vielleicht schaut das beim setzen auch einfach den Dateinamen an, stellt fest, dass das bereits angezeigte Bild den gleichen Namen hat, und lädt deswegen nicht neu.
Ich habe einen Zähler deklariert, der nach Löschen der Bilder bzw. neuer Aufnahme diesen einen anderen Namen zuweist.
Das Resultat: Es funktioniert.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dudu hat geschrieben:Danke für die höchst sarkastische Antwort. Zunächst könnte meine Frage bezüglich des Zwischenspeichers bestimmt auch ohne Code gelöst werden.
Schoen das du besser glaubst zu wissen, was wir brauchen, um dir zu helfen. Stimmt halt leider nur nicht.

Niemand kann erraten, dass du deine Kamera-Bilder auf das Dateisystem speicherst. Das ist nicht nur umstaendlich, verschwendet ein bisschen CPU, und macht je nach Speicherort deine SD-Karte muerbe. Es ist vor allem nicht im Sinne des Erfinders.

Stattdessen sollte man die Frames gleich als numpy-Array abgreifen (kann picamera), und dann als kivy-Textur darstellen lassen (http://stackoverflow.com/questions/2715 ... ay-in-kivy). Das numpy-Array dient dann gleich danach/davor zur Verarbeitung mit OpenCV verwandt werden, und man spart sich unnoetiges speichern/laden/durchnummerieren.
Astorek
User
Beiträge: 72
Registriert: Samstag 24. Januar 2009, 15:06
Kontaktdaten:

Um den Spuk mal aufzulösen: Kivy hat die (ggf. recht nette) Eigenschaft, dass einmal geladene Bilder nach einem Caching-Mechanismus intern gespeichert werden. Kommt einerseits besonders Anfängern entgegen, die z.B. in einer Schleife dauernd ein- und dieselbe Bilddatei vom Dateisystem lesen (wenn dann das Betriebssystem auch nicht cached, wird sich das Speichermedium herzlich dafür bedanken, wenn im Millisekunden-Rhythmus vom Dateisystem geladen wird). In diesem Fall hier ist der Caching-Mechanismus natürlich nicht erwünscht...

An dieser Stelle möchte ich für die englischsprachigen Leser auch auf die IMHO ausgezeichnete Kivy-DoKumentation hinweisen (Sonderpunkt Image und die Option "nocache"), die alles recht schön und nachvollziehbar erklärt inkl. der Aufschlüsselung sämtlicher Methodenparameter, ihren Erklärungen und Defaultwerten.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich denke das hat weniger mit IO load zu tun, sondern mehr damit, dass sie Texturen verwenden. Da arbeitet man immer mit einem Cache. Und lesen sollte auch nicht sooo schlimm sein. Das kommt dann ggf. aus dem FS Cache. Aber schreiben ist Stress, und SD Karten können das nicht gut ab.
Antworten