Hallo Forummitglieder,
ich bin gerade dabei, ein Photobox für meine Hochzeit selbst zu bauen. Hierbei habe ich mich hieran orientiert:
http://maltekueppers.de/dc/index.php?po ... Photobooth
Das Programm läuft und tut, was es soll. Ein Problem ist allerdings, dass während das Programm läuft, immer wieder kurz zum "Desktop" zurückgeswitcht wird.
Also in etwa so:
-Buzzer wird ausgelöst
-Sprung zurück zum Desktop
-vier Fotos werden gemacht
-Sprung zurück zum Desktop
-Ladebild wird angezeigt
-Sprung zurück zum Desktop
-Die vier Bilder wurden zu einem zusammengefügt. Dieses wird angezeigt
-Sprung zurück zum Desktop
-Jetzt werden in zufälliger Reihenfolge alte Bilder angezeigt, bis der Buzzer erneut ausgelöst wird.
Was mich stört sind wie beschrieben diese Sprünge zurück. Wenn das Programm läuft, soll ja nicht gesehen werden, was im Hintergrund läuft.
Kann mir jemand helfen, diesen "Fehler" zu eliminieren?
Ich hoffe, ich habe mich so ausgedrückt, dass man mich versteht
Vielen Dank schon mal im Voraus
Tommy
Sprünge bei Programmausführung
@mieth: Da kann man ohne Quelltext nicht wirklich etwas zu sagen. Das verlinkte Blog enthält ja nur Bruchstücke. Die im übrigen nicht gut sind, der Autor scheint da irgendwie in einer anderen Programmiersprache arbeiten zu wollen. So oft wie dort `gc.collect()` und ``del`` vorkommt, scheint er komische Vorstellungen von Python's Speicherverwaltung zu haben.
Bei den vielen `os.system()`-Aufrufen frage ich mich ja fast ob das übehaupt ein Python-Programm ist oder nicht doch ein Shell-Programm.Das Programm scheint bereits PIL/Pillow zu verwenden, ruft aber trotzdem für alles mögliche ImageMagick-Programme per `os.system()` auf. Was soll der Unsinn? Und selbst wenn man ImageMagick verwenden möchte: Es gibt eine Python-Anbindung an die `libmagick`, da muss man nicht erst eine Shell und darin dann Konsolenprogramme starten die letztlich die `libmagick` verwenden. Auch für das kopieren und löschen von Dateien muss man nicht die Programme ``cp`` und ``rm`` aufrufen. Wozu dann überhaupt Python?
Vermutlich, wenn ich mir den Blogbeitrag anschaue auf den sich der Autor dort bezieht, könnten die ”Sprünge” zustande kommen weil er nicht einmal ein Pygame-Fenster erstellt und damit dann durchgehend arbeitet, sondern das immer mal wieder schliesst und ein neues erstellt.
Bei den vielen `os.system()`-Aufrufen frage ich mich ja fast ob das übehaupt ein Python-Programm ist oder nicht doch ein Shell-Programm.Das Programm scheint bereits PIL/Pillow zu verwenden, ruft aber trotzdem für alles mögliche ImageMagick-Programme per `os.system()` auf. Was soll der Unsinn? Und selbst wenn man ImageMagick verwenden möchte: Es gibt eine Python-Anbindung an die `libmagick`, da muss man nicht erst eine Shell und darin dann Konsolenprogramme starten die letztlich die `libmagick` verwenden. Auch für das kopieren und löschen von Dateien muss man nicht die Programme ``cp`` und ``rm`` aufrufen. Wozu dann überhaupt Python?
Vermutlich, wenn ich mir den Blogbeitrag anschaue auf den sich der Autor dort bezieht, könnten die ”Sprünge” zustande kommen weil er nicht einmal ein Pygame-Fenster erstellt und damit dann durchgehend arbeitet, sondern das immer mal wieder schliesst und ein neues erstellt.
hallo blackjack danke für die schnelle antwort
Das komplette python skript steht ganz unten in dem link vor den kommentare
da musste drauf klicken (Der komplette Code: photobooth.py)
ich habe gedacht das eigenlich dieser eintrag im skript das problem beheben sollte: pygame.display.flip() # update the display :K
,das tut es aber leider nicht, kann es sein das ich noch was installieren muss z.b ein modul oder ein teil von einem modul
(das mit dem löschen und der speicherung auf usb stick habe ich rausgenommen in meinen skript, bei mir findet die speicherung auf der
sd karte (128Gb) statt.)
Das komplette python skript steht ganz unten in dem link vor den kommentare
da musste drauf klicken (Der komplette Code: photobooth.py)
ich habe gedacht das eigenlich dieser eintrag im skript das problem beheben sollte: pygame.display.flip() # update the display :K
,das tut es aber leider nicht, kann es sein das ich noch was installieren muss z.b ein modul oder ein teil von einem modul
(das mit dem löschen und der speicherung auf usb stick habe ich rausgenommen in meinen skript, bei mir findet die speicherung auf der
sd karte (128Gb) statt.)
@mieth: durch den Spaghetti-Code möchte sich eigentlich niemand durcharbeiten. Der Kommentar in »display_pics« sagt doch schon alles:
Der Schreiber wundert sich, warum beim zweiten man Initialisieren von Pygame irgendetwas nicht so ganz richtig funktioniert. Ganz einfach, weil man Pygame nur ein mal intitialisieren sollte!
Wenn das Skript läuft, hast Du eigentlich alle Module installiert.
Code: Alles auswählen
# this section is an unbelievable nasty hack - for some reason Pygame
# needs a keyboardinterrupt to initialise in some limited circs (second time running)
Wenn das Skript läuft, hast Du eigentlich alle Module installiert.
Das Problem was du hast ist nur das Symptom eines viel größeren Problems auf das BlackJack in seinem Beitrag schon teilweise eingegangen ist.
Bei dem Schreiben des Skripts sind soviele schlechte Entscheidungen gefällt worden, sowohl bei einigen Details als auch bei grundlegenden Dingen, dass man dort nicht sinnvoll irgendwas beheben oder verbessern kann.
Man kann eigentlich nur empfehlen dieses Skript zu vergessen und bei Null anzufangen. Vorallem wenn man bedenkt dass dieses Projekt bei deiner Hochzeit verwenden möchtest und du dort sicherlich besseres zu tun hast als dich damit zu beschäftigen dass deine Photobox nicht mehr funktioniert.
Bei dem Schreiben des Skripts sind soviele schlechte Entscheidungen gefällt worden, sowohl bei einigen Details als auch bei grundlegenden Dingen, dass man dort nicht sinnvoll irgendwas beheben oder verbessern kann.
Man kann eigentlich nur empfehlen dieses Skript zu vergessen und bei Null anzufangen. Vorallem wenn man bedenkt dass dieses Projekt bei deiner Hochzeit verwenden möchtest und du dort sicherlich besseres zu tun hast als dich damit zu beschäftigen dass deine Photobox nicht mehr funktioniert.
Hallo,
vielen Dank für eure Hilfe und eure Mühe.
Die Sache ist ja, dass eigentlich alles super fuktioniert. Es werden Bilder gemacht, die werden richtig zusammengefügt und alles.
Nur das Springen ist irgendwie doof....
Ich habe den Code mal angehängt. Es wäre cool, wenn ihr euch das noch einmal anschauen könntet. Vielleicht gibt es ja doch eine einfache Lösung für mich. Ich bin selbst noch Anfänger, wie ihr sicher gemerkt habt. Und von Neuem beginnen, gibt der Zeitplan eigentlich nicht her...
Danke noch einmal.
Viele Grüße
Mieth
vielen Dank für eure Hilfe und eure Mühe.
Die Sache ist ja, dass eigentlich alles super fuktioniert. Es werden Bilder gemacht, die werden richtig zusammengefügt und alles.
Nur das Springen ist irgendwie doof....
Ich habe den Code mal angehängt. Es wäre cool, wenn ihr euch das noch einmal anschauen könntet. Vielleicht gibt es ja doch eine einfache Lösung für mich. Ich bin selbst noch Anfänger, wie ihr sicher gemerkt habt. Und von Neuem beginnen, gibt der Zeitplan eigentlich nicht her...
Code: Alles auswählen
#!/usr/bin/env python
# created by chris@drumminhands.com
# see instructions at http://www.drumminhands.com/2014/06/15/ ... oto-booth/
import traceback
import os
import glob
import time
from time import sleep
import RPi.GPIO as GPIO
import picamera
import atexit
import sys
import random
from PIL import Image
import smtplib
import socket
import pygame
from pygame.locals import *
from signal import alarm, signal, SIGALRM, SIGKILL
import gc
import subprocess
########################
### Variables Config ###
########################
led1_pin = 37 # LED 1 GPIO 26
led2_pin = 15 # LED 2 GPIO 22
led3_pin = 38 # LED 3 GPIO 20
led4_pin = 33 # LED 4 GPIO 13
button1_pin = 16 # GPIO 23 pin Knopf (taster) Bilder machen
button2_pin = 35 # GPIO 19 pin Knopf (taster) Pi Runterfahren
button3_pin = 36 # GPIO 16 pin Neustart oder programm beenden
total_pics = 4 # Wieviele Bilder gemacht werden
capture_delay = 0.5 # delay between pics
prep_delay = 1 # number of seconds at step 1 as users prep to have photo taken
gif_delay = 100 # How much time between frames in the animated gif
file_path = '/home/pi/Desktop/fotos/' #Speicherort der Bilder
w = 1230 #max.1440
h = 950 #amx.1080
#monitor_w = 800 #Mieth bildschirm weite
#monitor_h = 600 #Mieth bildschirm hohe
hoehe_klein = 1440 #1920 #1440 #variabele von michi montage
breite_klein = 1280 #1280 #1080 #variabele von michi montage
transform_x = 1230 #weite von den bilder die wiedergegen sollen max.1440
transfrom_y = 950 #hoehe von den bilder die wiedergegen sollen max.1080
offset_x = 0 #350 #how far off to left corner to display photos
offset_y = 0 #wie weit von zur linken Ecke, um Fotos zu zeigen
replay_delay = 3 # how much to wait in-between showing pics on-screen after taking
replay_cycles = 3 # how many times to show each photo on-screen after taking
start_again = False
####################
### Other Config ###
####################
GPIO.setmode(GPIO.BOARD)
GPIO.setup(led1_pin,GPIO.OUT) # LED 1
GPIO.setup(led2_pin,GPIO.OUT) # LED 2
GPIO.setup(led3_pin,GPIO.OUT) # LED 3
GPIO.setup(led4_pin,GPIO.OUT) # LED 4
GPIO.setup(button1_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Prellung des tasters verhindern taster 1
GPIO.setup(button2_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Prellung des tasters verhindern taster 2
GPIO.setup(button3_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Prellung des tasters verhindern taster 3
GPIO.output(led1_pin,False);
GPIO.output(led2_pin,False);
GPIO.output(led3_pin,False);
GPIO.output(led4_pin,False); #for some reason the pin turns on at the beginning of the program. why?????????????????????????????????
#################
### Functions ###
#################
def lightshow(stime):
GPIO.output(led1_pin,False)
GPIO.output(led2_pin,False)
GPIO.output(led3_pin,False)
sleep(stime)
GPIO.output(led1_pin,True)
sleep(stime)
GPIO.output(led2_pin,True)
sleep(stime)
GPIO.output(led3_pin,True)
sleep(stime)
def reset_event_detection_shutdown():
sleep(0.5)
GPIO.remove_event_detect(button2_pin)
sleep(0.1)
GPIO.add_event_detect(button2_pin, GPIO.FALLING, callback=shut_it_down, bouncetime=300)
def reset_event_detection_reboot():
sleep(0.5)
GPIO.remove_event_detect(button3_pin)
sleep(0.1)
GPIO.add_event_detect(button3_pin, GPIO.FALLING, callback=exit_photobooth, bouncetime=300)
def cleanup():
print('Fotobox Progamm sofort beendet')
GPIO.cleanup()
atexit.register(cleanup)
def shut_it_down(channel):
sleep(0.5)
counter=0
while GPIO.input(channel) == GPIO.LOW :
counter=counter+1
sleep(0.1)
if (counter >= 8):
print str(counter) + "counter"
print "PI Runterfahren..."
GPIO.remove_event_detect(button2_pin)
lightshow(1)
#GPIO.output(led1_pin,True);
#GPIO.output(led2_pin,True);
#GPIO.output(led3_pin,True);
#GPIO.output(led4_pin,True);
time.sleep(3)
os.system("sudo shutdown now -h")
else:
print "Press longer to shutdown!"
print str(counter) + "counter"
reset_event_detection_shutdown()
def exit_photobooth(channel):
sleep(0.5)
print "reboot Call"
counter=0
while GPIO.input(channel) == GPIO.LOW :
counter=counter+1
print "B-Press"
sleep(0.1)
if (counter >= 2):
print str(counter) + "counter"
print "Rebooting..."
GPIO.remove_event_detect(button3_pin)
lightshow(1)
#GPIO.output(led1_pin,True);
#GPIO.output(led2_pin,True);
#GPIO.output(led3_pin,True);
#GPIO.output(led4_pin,True);
time.sleep(3)
GPIO.cleanup() #mieth
os.system ("sudo killall python ")#killall python #mieth
else:
print "Press longer to reboot!"
print str(counter) + "counter"
reset_event_detection_reboot()
def clear_pics(foo): #why is this function being passed an arguments?
#delete files in folder on startup
files = glob.glob(file_path + '*')
for f in files:
os.remove(f)
#light the lights in series to show completed
print "Deleted previous pics"
GPIO.output(led1_pin,False); #turn off the lights
GPIO.output(led2_pin,False);
GPIO.output(led3_pin,False);
GPIO.output(led4_pin,False)
pins = [led1_pin, led2_pin, led3_pin, led4_pin]
for p in pins:
GPIO.output(p,True);
sleep(0.25)
GPIO.output(p,False);
sleep(0.25)
def display_pics(jpg_group):
# this section is an unbelievable nasty hack - for some reason Pygame
# needs a keyboardinterrupt to initialise in some limited circs (second time running)
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
signal(SIGALRM, alarm_handler)
alarm(3)
try:
pygame.init()
screen = pygame.display.set_mode((w,h),pygame.FULLSCREEN)
alarm(0)
except Alarm:
raise KeyboardInterrupt
pygame.display.set_caption('Photo Booth Pics')
pygame.mouse.set_visible(False) #hide the mouse cursor
filename = file_path + jpg_group + "-montage.jpg"
img=pygame.image.load(filename)
img = pygame.transform.scale(img,(transform_x,transfrom_y))
screen.blit(img,(offset_x,offset_y))
pygame.display.flip() # update the display
time.sleep(replay_delay*4) # pause
def countdown_overlay( camera ):
n=4
for i in range(1,n):
gc.collect()
# Load the arbitrarily sized image
img = Image.open('/home/pi/Desktop/wait/'+ str(i)+ 'wait.jpg')
# Create an image padded to the required size with
# mode 'RGB'
pad = Image.new('RGB', (
((img.size[0] + 31) // 32) * 32,
((img.size[1] + 15) // 16) * 16,
))
# Paste the original image into the padded one
pad.paste(img, (0, 0))
# Add the overlay with the padded image as the source,
# but the original image's dimensions
o = camera.add_overlay(pad.tostring(), size=img.size)
# By default, the overlay is in layer 0, beneath the
# preview (which defaults to layer 2). Here we make
# the new overlay semi-transparent, then move it above
# the preview
o.alpha = 100 #128
o.layer = 3
sleep(1)
camera.remove_overlay(o)
del img
del pad
def process_pics(now):
# this section is an unbelievable nasty hack - for some reason Pygame
# needs a keyboardinterrupt to initialise in some limited circs (second time running)
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
signal(SIGALRM, alarm_handler)
alarm(3)
try:
pygame.init()
screen = pygame.display.set_mode((w,h),pygame.FULLSCREEN)
alarm(0)
except Alarm:
raise KeyboardInterrupt
pygame.display.set_caption('Photo Booth Pics')
pygame.mouse.set_visible(False) #hide the mouse cursor
filename = "/home/pi/Desktop/wait/wait4.jpg"
img=pygame.image.load(filename)
img = pygame.transform.scale(img,(transform_x,transfrom_y))
screen.blit(img,(offset_x,offset_y))
pygame.display.flip() # update the display
GPIO.output(led3_pin,True) #turn on the LED
graphicsmagick = "montage "+ file_path + now + "-01.jpg " + file_path + now + "-02.jpg " + file_path + now + "-03.jpg " + file_path + now + "-04.jpg -geometry " + str(hoehe_klein) +"x" + str(breite_klein) + "+2+2 "+ file_path + now + "-montage.jpg "
os.system(graphicsmagick)
bilder_wech="cp "+ file_path + now + "-01.jpg " + file_path + now + "-02.jpg " + file_path + now + "-03.jpg " + file_path + now + "-04.jpg "+ file_path + "single/"
os.system(bilder_wech)
bilder_wech="rm -f "+ file_path + now + "-01.jpg " + file_path + now + "-02.jpg " + file_path + now + "-03.jpg " + file_path + now + "-04.jpg "
os.system(bilder_wech)
pygame.quit()
# define the photo taking function for when the big button is pressed
def start_photobooth():
################################# Begin Step 1 #################################
#print "Los gehts"
start_again = False
GPIO.output(led2_pin,True);
camera = picamera.PiCamera()
#pixel_width = 1920 #mieth
#pixel_height = monitor_h * pixel_width // monitor_w #mieth
#camera.resolution = (pixel_width, pixel_height) #mieth
#camera.resolution = (1920, 1080)#bidausgabe und aufloesung aendern von bildern
camera.framerate = 30 #Standard (24) Bildfrequenz
camera.vflip = True
camera.hflip = True # False mieth
camera.rotation = 180 #180 Quer format und 90 Hochformat (rotation)
#camera.saturation = -100 #Schwarz Weiss Fotos mieth
camera.start_preview()
GPIO.output(led2_pin,False);
sleep(0.5)
countdown_overlay(camera)
i=4 #iterate the blink of the light in prep, also gives a little time for the camera to warm up
while i < prep_delay :
GPIO.output(led1_pin,True); sleep(.5)
GPIO.output(led1_pin,False); sleep(.5); i+=1
################################# Begin Step 2 #################################
#print "Mache Bilder"
now = time.strftime("%Y%m%d%H%M%S") #get the current date and time for the start of the filename
try: #take the photos
for i, filename in enumerate(camera.capture_continuous(file_path + now + '-' + '{counter:02d}.jpg')):
GPIO.output(led2_pin,True) #turn on the LED
print(filename)
graphicsmagick = "composite -dissolve 75 -gravity southwest /home/pi/test.png " + filename + " " + filename + "&" # dissolve <prozent> 0 = voll transparent 100 = voll dargestellt
os.system(graphicsmagick)
sleep(0.5) #pause the LED on for just a bit
GPIO.output(led2_pin,False) #turn off the LED
if i == total_pics-1:
break
else:
sleep(capture_delay) # pause in-between shots
countdown_overlay(camera)
finally:
camera.stop_preview()
camera.close()
########################### Begin Step 3 #################################
#print "Bearbeite Bilder fuer Montage..."
process_pics(now)
GPIO.output(led3_pin,True) #turn on the LED
GPIO.output(led3_pin,False) #turn off the LED
########################### Begin Step 4 #################################
#GPIO.output(led4_pin,True) #turn on the LED
GPIO.output(led1_pin,True)
try:
display_pics(now)
except Exception, e:
tb = sys.exc_info()[2]
traceback.print_exception(e.__class__, e, tb)
pygame.quit()
#print "Beendet"
#GPIO.output(led4_pin,False) #turn off the LED
#screen.fill((255,255,255))
GPIO.output(led1_pin,False)
random_pics(file_path)
def random_pics(file_path):
GPIO.output(led2_pin,True)
idle = True
GPIO.add_event_detect(button1_pin, GPIO.FALLING)
if GPIO.event_detected(button1_pin):
#pygame.quit()
print "IDLE set to false"
idle = False
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
signal(SIGALRM, alarm_handler)
alarm(3)
try:
pygame.init()
screen = pygame.display.set_mode((w,h),pygame.FULLSCREEN)
alarm(0)
except Alarm:
raise KeyboardInterrupt
while not GPIO.event_detected(button1_pin) :
piclist = list()
x = 0
for infile in glob.glob(os.path.join(file_path,'*.jpg')):
piclist.append(infile)
print random.choice(piclist)
pygame.display.set_caption('Photo Booth Pics')
pygame.mouse.set_visible(False) #hide the mouse cursor
filename = random.choice(piclist)
del piclist
img=pygame.image.load(filename)
img = pygame.transform.scale(img,(transform_x,transfrom_y))
screen.blit(img,(offset_x,offset_y))
pygame.display.flip() # update the display
sleep(3)
print "naechstes bild..."
gc.collect()
pygame.quit()
print "killed random image process"
GPIO.remove_event_detect(button1_pin)
start_again = True
GPIO.output(led2_pin,False)
####################
### Main Program ###
####################
# when a falling edge is detected on button2_pin and button3_pin, regardless of whatever
# else is happening in the program, their function will be run
GPIO.add_event_detect(button2_pin, GPIO.FALLING, callback=shut_it_down, bouncetime=300)
#choose one of the two following lines to be un-commented
GPIO.add_event_detect(button3_pin, GPIO.FALLING, callback=exit_photobooth, bouncetime=300) #use third button to exit python. Good while developing
#GPIO.add_event_detect(button3_pin, GPIO.FALLING, callback=clear_pics, bouncetime=300) #use the third button to clear pics stored on the SD card from previous events
print "Fotobox startet..."
GPIO.output(led1_pin,True); #light up the lights to show the app is running
time.sleep(0.5)
GPIO.output(led2_pin,True);
time.sleep(0.5)
GPIO.output(led3_pin,True);
time.sleep(0.5)
GPIO.output(led4_pin,True);
#Falsche und defekte Bilder entfernen
systembefehl = "rm -f /home/pi/Desktop/*-0*.jpg &"
os.system(systembefehl)
gc.enable()
print "Fotobox ist gestartet"
print "OK"
while True:
while start_again == False:
GPIO.wait_for_edge(button1_pin, GPIO.FALLING)
start_again = True
GPIO.output(led1_pin,False); #turn off the lights
GPIO.output(led2_pin,False);
GPIO.output(led3_pin,False);
GPIO.output(led4_pin,False);
GPIO.output(led1_pin,True); #light up the lights to show the app is running
time.sleep(0.3) #debounce
start_photobooth()
Viele Grüße
Mieth
Zuletzt geändert von Anonymous am Montag 2. Januar 2017, 12:41, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
@mieth: Leider hab ich heute keine Zeit mehr, aber morgen kann ich dir vielleicht helfen, den Code etwas aufzuräumen. Er scheint mir, nach kurzem überfliegen, ziemlich unübersichtlich. Vieles ist völlig unpythonisch. BlackJack hat ja schon darauf hingewiesen. So, wie der Code jetzt aussieht, ist er IMO wenig brauchbar. Dass er irgendwie zu funktionieren scheint, mag ja sein, bis zu dem Moment, wo er das - warum auch immer - nicht mehr tut und man in dem ganzen Ducheinander nicht herausfinden kann, woran es liegt, weil alles von allem abhängt und die Ablaufsteuerung über den gesamten Code verteilt ist (schau zB. mal, wo mit start_again operiert wird). Wie gesagt, morgen habe ich mehr Zeit.
In specifications, Murphy's Law supersedes Ohm's.
-
- User
- Beiträge: 1
- Registriert: Montag 2. Januar 2017, 11:14
Hallo ich habe das selbe Projekt mit dem selben Code hast du denn schon erfolge verzeichnen können??
gesundes neues und vielen dank
Gruß Robby
gesundes neues und vielen dank
Gruß Robby