Photomaton automatique à base de Raspberry Pi

Photobooth (boîte en carton) branché à la TV
Photomaton minimaliste pour le moment, mais parfaitement utilisable (boîte faite en carton)

Résumé :
Article en 2 parties
1 – Tutoriel pour réaliser en quelques minutes un photomaton automatique à l’aide d’un Raspberry Pi et d’un bouton poussoir.
2 – Tutoriel pour ajouter un bouton poussoir de redémarrage (reboot) et un bouton poussoir d’extinction (shutdown).

Bonjour,

Cette fois, ce n’est pas pour aider quelqu’un d’un forum que j’ai réalisé ce “montage” … mais … suite à une question d’un forumeur en rapport avec le sujet.
Oui, ça reste proche ; c’est à cause des autres 🙂

Je n’avais jamais essayé de réaliser un photomaton (trop souvent appelé Photobooth à cause du terme Anglais) alors qu’on trouve légion de questions/sites/tutos sur le sujet.
Vous vous en doutez, j’y ai souvent pensé ces dernières années.
Cependant, je ne m’étais jamais aventuré dans l’histoire car j’avais peur de ne pas y arriver et, surtout, je ne voulais pas acheter de matériel (oui, c’est un aspect récurrent de ma personnalité 😉 ; j’avoue).

Mais … en fait … je n’ai pas besoin d’acheter puisque un simple bouton fera l’affaire (“Commutateur momentané à bouton-poussoir” dans le jargon je crois).
Ben oui ! Il m’en reste 4 de l’époque de mon bartop maison ; ils sont dans une caisse au sein même de LA caisse “informatique” du garage truc appelé garage faisant office de débarras.
Content Alban 🙂

Et, je vous le dis tout de suite : Réaliser un Photomaton = c’est HYPER facile et rapide !

A la fin de cet article, vous aurez donc un photomaton (ou Photobooth pour les Anglophone ou un PiBooth pour les “branchés”).
C’est à dire un Raspberry Pi pouvant prendre une photo par simple appui sur un bouton.
Et cela va vous prendre moins de 10 minutes si Raspbian est déjà installé.

Et, après, en bonus, j’ai ajouté un cadeau 🙂

En effet, après un petit tour du Web, j’ai voulu corser le tout.
Oui, ça sera mon premier script en python.
Oui, je veux modifier ce script pour y mettre ma patte.
Mais, en plus, je veux ajouter un truc : la gestion du photomaton sans aucune interface clavier/souris.
En bref, pouvoir arrêter le Raspberry Pi en appuyant juste sur un bouton au cas où il serait dans un meuble en mode Photomaton.

Actuellement, je vous écris depuis le Raspberry Pi3B+ qui sert de Photomaton/Photobooth (j’ai coupé le script et branché clavier/souris).
Cela pour prouver que ce Raspberry Pi peut encore être utilisable comme PC.

C’est mon Rpi3B+ avec Raspbian Stretch avec Bureau graphique (mais pas la version “full”).
Mon image est celle du 13/11/2018 réinstallée fraîchement ce matin pour vérifier que les tutos fonctionnaient bien.
J’ai simplement configuré le Rpi comme dans cet article : Installation de Raspbian Stretch.

1 – Tutoriel pour le Photomaton

Finalement, la mise en place du “photobooth” est très simple et tient en 4 étapes :

  1. On installe Raspbian comme dans l’article précédemment cité.
  2. On active ensuite le SSH (et VNC si besoin) et la Caméra en allant dans l’utilitaire de configuration nommé “Configuration du Raspberry Pi” (Menu Framboise –> Préférences).
  3. Évidemment, il vous faut le module caméra (ou RaspiCam) à connecter au port CSI
  4. On utilise un script écrit en python

Mon script est énormément basé sur celui que nous trouvons tous sur le Net à un moment ou un autre et qui s’appelle pibooth.py (lien direct par respect).

J’ai réécrit “mon” script, mais je n’ai rien inventé. D’autant que je découvre le python !
L’inspiration très forte. Mes adaptations apportées sont :

  • Modification des GPIO utilisés (le BCM24 soit le port 18 + la masse 20)
  • Ajout d’une image de fond + un texte d’accueil
  • Ajout d’un effet sonore à l’écran d’accueil
  • Ajout d’un temporisateur pour que la photo prise s’affiche secondes
  • Ajout d’un retour à l’écran d’accueil.

Bref, rien de révolutionnaire, mais je suis content puisque je débute totalement en python.
Bon, comme je suis fier et partageur, voici mon script.

Créez le fichier avec nano photomaton.py
puis collez ceci :

#!/usr/bin/python3
# -*- coding: utf-8 -*
import RPi.GPIO as GPIO
import time
from datetime import datetime
from PIL import Image
import pygame
from pygame.locals import *
import os

GPIO.setmode(GPIO.BCM) #Attention au choix du port ; référez-vous au site https://fr.pinout.xyz/
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)

pygame.init()
screen = pygame.display.set_mode((0,0),pygame.FULLSCREEN)
width, height = screen.get_size()

pygame.mixer.init()
son = pygame.mixer.Sound('/home/pi/Photomaton/son.wav')
canal = son.play()


def PrisePhoto(NomPhoto): #prendre une photo avec Raspistill
    #command = "sudo raspistill -t 1000 -w 960 -h 540 -o "+ NomPhoto +" -q 100" #prend une photo
    command = "sudo raspistill -t 1000 -w 1200 -h 675 -o "+ NomPhoto +" -q 100" #prend une photo
    os.system(command)

def AfficherPhoto(NomPhoto): # affiche NomPhoto
    print("loading image: " + NomPhoto)
    background = pygame.image.load(NomPhoto);
    background.convert_alpha()
    background = pygame.transform.scale(background,(width,height))
    screen.blit(background,(0,0),(0,0,width,height))
    pygame.display.flip()


def decompte():
  AfficherTexte("      5")
  time.sleep(1)
  AfficherTexte("      4")
  time.sleep(1)
  AfficherTexte("      3")
  time.sleep(1)
  AfficherTexte("      2")
  time.sleep(1)
  AfficherTexte("      1")
  time.sleep(1)
  AfficherTexte("souriez")


def AfficherTexte(message): # pour pouvoir afficher des messages sur un font noir 
    screen.fill(pygame.Color(0,0,0))
    font = pygame.font.SysFont("verdana", 250, bold=1)
    textsurface = font.render(message, 1, pygame.Color(255,255,255))
    screen.blit(textsurface,(35,40))
    pygame.display.update()


def AfficherTexteTransparent(message): # pour pouvoir afficher des messages en conservant le font 
    font = pygame.font.SysFont("verdana", 50, bold=1)
    textsurface = font.render(message, 1, pygame.Color(255,255,255))
    screen.blit(textsurface,(35,40))
    pygame.display.update()


def AfficherTexteAccueil(message): # Afficher un Texte sur l'image d'accueil (ou à la place) 
    font = pygame.font.SysFont("verdana", 50, bold=1)
    textsurface = font.render(message, 1, pygame.Color(100,150,200))
    screen.blit(textsurface,(35,40))
    pygame.display.update()


if (os.path.isdir("/home/pi/Desktop/photos") == False): # si le dossier pour stocker les photos n'existe pas       
   os.mkdir("/home/pi/Desktop/photos")                  # alors on crée le dossier (sur le bureau)
   os.chmod("/home/pi/Desktop/photos",0o777)            # et on change les droits pour pouvoir effacer des photos

AfficherPhoto("/home/pi/Photomaton/accueil.jpg")
AfficherTexteAccueil("Installez-vous et appuyez sur le bouton pour prendre une photo")


while True : #boucle jusqu'a interruption
  try:
        print "\n attente boucle"
        
        #on attend que le bouton soit pressé
        GPIO.wait_for_edge(24, GPIO.FALLING)
        # on a appuyé sur le bouton...


        #on lance le décompte
        decompte()


        #on génère le nom de la photo avec heure_min_sec
        date_today = datetime.now()
        nom_image = date_today.strftime('%d_%m_%H_%M_%S')

       
        #on déclenche la prise de photo
        chemin_photo = '/home/pi/Desktop/photos/'+nom_image+'.jpeg'
        PrisePhoto(chemin_photo) #Déclenchement de la prise de photo


        #on affiche la photo
        AfficherPhoto(chemin_photo)


        #on affiche un message
        AfficherTexteTransparent("OK ; c'est dans la boite ...")
	time.sleep(5) #Ajout d'un temps d'affichage afin de repartir sur l'accueil ensuite


        #on recommence en rechargeant l'écran d'accueil
	AfficherPhoto("/home/pi/Photomaton/accueil.jpg")
	AfficherTexteAccueil("Installez-vous devant l'objectif et appuyez sur le bouton noir pour prendre une photo")
	pygame.mixer.init()
	son = pygame.mixer.Sound('/home/pi/Photomaton/son.wav')
	canal = son.play()


        if (GPIO.input(24) == 0): #si le bouton est encore enfoncé (sont etat sera 0)
              print "Ho ; bouton  appuyé !!! Je dois sortir ; c'est le chef qui l'a dit !"
              break # alors on sort du while 
 

  except KeyboardInterrupt:
    print 'sortie du programme!'
    raise

GPIO.cleanup()           # reinitialisation GPIO lors d'une sortie normale



On valide avec “Ctrl”+”x” puis “o” puis “Entrée”.

image avec dessin d'un appareil photo et texte invitant à s'installer et appuyer sur le bouton
–> Image d’accueil personnelle pour mon photomaton (à la dimension de mon écran)

Avant de tester, on va créer un dossier “Photomaton” avec mkdir /home/pi/Photomaton
On y insère l’image de fond pour l’écran d’accueil et le fichier son désiré (ou pas ; vous faites comme vous voulez ; c’était un simple test de ma part au départ).
Mon image est simplement une insertion d’une image Libre de Droit sur un fond noir + incrustation d’un texte en blanc.
L’icône vient de pixabay.com.
Je précise que vous pouvez utiliser mon image en la téléchargeant en cliquant dessus (1080x1920px).

Par principe, on teste la chose avec un sudo python /home/pi/photomaton.py puis “Entrée” … et …
Heu … attendez !!!
Une fois le script lancé, vous pourrez appuyer sur le bouton pour lancer la procédure de prise de photo.
MAIS … comment on sort du script ???
Il suffit d’appuyer “durablement” sur le bouton jusqu’à la fermeture du script (sur le mien, c’est 15 secondes si on repart de l’écran d’accueil).

Mais, vous n’allez pas vous faire avoir puisque je n’ai pas encore abordé le branchement du bouton.
Et c’est volontaire 🙂

Photo d'un bouton poussoir
–> Un joli bouton poussoir (et pas un point) noir !

Pour le bouton, j’ai donc opté pour un simple bouton d’arcade (sur l’image, c’est le bouton noir ; cliquez pour zoomer).
La connexion est réalisée à l’aide du câblage fourni avec.

On connecte donc le câble au bouton puis aux ports GPIO.
On lance le script en essai avec sudo python /home/pi/photomaton.py et ça doit lancer un écran avec “Installez-vous et appuyez sur le bouton pour prendre une photo”.
C’est bon ?
Alors, appuyez 1 fois brève sur le bouton et 🙂

Ensuite, appuyez à nouveau mais sans relâcher durant 15 secondes.
Ça va prendre la seconde photo puis l’afficher puis quitter le script (c’est bon, vous pouvez relâcher le bouton 😉 et vous servir de vos 2 mains pour taper du code).

Comme tout s’est bien passé, on va automatiser la chose :
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
On ajoute python /home/pi/photomaton.py à la dernière ligne et on valide avec les habituels “Ctrl”+”c” puis “o” puis “Entrée”.

Ça donnera ceci :

@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
point-rpi
python /home/pi/photomaton.py

A ce stade, vous redémarrez votre Rpi et vous devez avoir un Photomaton automatique car le script sera lancé au chargement de votre interface graphique.

C’est OK chez vous?

Bon, je vais faire un tour pour trouver des chaussures pour le N°4 et je reviens pour la partie :
Ajout d’un bouton de redémarrage + un bouton d’extinction.
A tout …

TaDa ; me revoilà.

Bon, on avait trouvé des Vans à 25 Euros (C’est les Soldes) … mais avec 1 pied en 35 et l’autre en 36.
Ho, les nazes !
Évidemment, je n’ai pas pris = il était déçu !!!
Quoi ?
Ha oui ; l’automatisation !
(Pffff … Comment ils s’en fichent de ma vie)

2 – Tutoriel pour piloter le Raspberry Pi avec 2 boutons poussoirs

Raspberry Pi + RaspiCam + les 3 boutons poussoirs
–> A l’état prototype, voici le photomaton et ses boutons de pilotage. C’est fonctionnel, mais “nu” pour le moment.

Alors, on termine par rendre la chose totalement automatique en chargeant ce script avant même la séquence graphique (comme ça, ça fonctionne aussi en mode console).
Édition de rc.local avec sudo nano /etc/rc.local
On y insère sudo python3 /home/pi/bouton-extinction.py& juste avant la ligne # Print the IP address
Le fichier sera :

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
sudo python3 /home/pi/bouton-extinction.py&
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0

Comme d’habitude, “Ctrl”+”x” puis “o” puis “Entrée”.

Ensuite, création du script avec sudo nano /home/pi/bouton-extinction.py.

Vous pouvez fairre un copier/coller de ce code :

#!/usr/bin/python3

#on importe les modules nécessaires
import time
import os
import RPi.GPIO as GPIO

#on met RPi.GPIO en mode notation BCM (numéro des pins ; ne vous trompez pas ; voir https://fr.pinout.xyz)
GPIO.setmode(GPIO.BCM)

#on initialise le GPIO 13 en écoute (broche physique 33 mais BCM pin 13)
GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#on initialise le GPIO 26 en écoute (broche physique 37 mais BCM pin 26)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)


#on définit la fonction appelée par la pression du bouton
def reboot(channel):
     #on affiche un message de confirmation (visible si écran connecté)
     print("Appui détecté sur le GPIO 13 = redémarrage demandée")
     #on reinitialise les GPIO
     GPIO.cleanup()
     #on lance la commande d'extinction
     os.system('sudo reboot')

#on définit la fonction appelée par la pression du bouton
def extinction(channel):
     #on affiche un message de confirmation (visible si écran connecté)
     print("Appui détecté sur le GPIO 26 = extinction demandée")
     #on reinitialise les GPIO
     GPIO.cleanup()
     #on lance la commande d'extinction
     os.system('sudo poweroff')


#on met les boutons en écoute
GPIO.add_event_detect(13, GPIO.FALLING, callback=reboot)
GPIO.add_event_detect(26, GPIO.FALLING, callback=extinction)

#on lance une boucle infinie, pour garder le script actif
while 1:
     #Avec une légère pause entre chaque boucle dans le but de réduire la charge CPU
     time.sleep(0.02)

#on réinitialise les ports GPIO en sortie de script
GPIO.cleanup()

On a donc un double script avec un reboot sur un bouton et un shutdown sur l’autre.

J’ai choisi mes GPIO pour les 2 scripts selon un protocole scientifique vérifié et indispensable :
Je voulais pouvoir passer les fils à travers le boitier mais pouvoir refermer le boitier alors que la partie connectable au GPIO est grosse et en un module 🙂
Bref, il fallait le GPIO utile et la masse soit côte-à-côte dans les 3 cas, mais pas les uns à côté des autres et pas sur la zone des “pattes” (les clips) du couvercle.
Donc libre à vous de faire autrement selon vos câbles et votre boîtier.

Allez, vous tentez un redémarrage ?

Vous aurez donc un Raspberry Pi qui devriendra un photomaton (photobooth en Anglais) au démarrage.
Avec un bouton pour réaliser un cliché.
Ce cliché sera enregistré dans un dossier sur le bureau (ce chemin peut se modifier)
Après affichage de 5 secondes de la photo, on a un retour à l’écran d’accueil.
Pour que cela fonctionne sans rien, le dispositif dispose de 2 autres boutons : “Redémarrer” et “Éteindre”.

Maintenant, à vous de réaliser la caisse/boîte/cabine que vous voulez autour de ce projet.

Pour le moment,le mien ressemble à ça 😀
(visuel à venir)

Si vous en faites un sympa/drôle/bizarre/décalé/original/traditionnel/… vous pouvez m’envoyer des photos pour publication (les images seront alors sous Licence Libre CC BY-SA 3.0 FR comme tout mon site).

Édit du 09/01/2019 au soir :
Pour être bien sûr que tout fonctionne parfaitement, je viens d’installer Raspbian sur une carte SD Sandisk Ultra de 16 Go achetée ce jour à 8,99 Euros à Leclerc (belle promo).
J’ai simplement appliqué les 2 parties de cet article et je confirme que tout fonctionne parfaitement !

A propos de Alban

Papa de 4 enfants étant lui même resté un enfant. Tombé par obligation dans l'informatique à 22 ans pour le boulot et s'étant "un peu" pris au jeu ... Pas un génie de l'informatique (loin de là), mais intéressé et carrément orienté Linux et entraide.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*