PiCamera & Python – programmiamo la webcam su Raspberry Pi

meccanismo-complesso-python-picamera-programmare-la-webcam-su-raspberry-pi

Introduzione

In questo articolo scopriremo insieme come utilizzare la webcam integrabile su Raspberry: la PiCamera. Questo modulo aggiuntivo di Raspberry Pi è un accessorio da non sottovalutare e lo consiglio vivamente a tutti quelli che vogliono esplorare una parte del mondo di Raspberry: la possibilità di fare foto e video in HD. Ma anche quello di fare analisi delle immagini in Python, grazie alle librerie che mette a disposizione, tra cui OpenCV

  • Raspberry Pi
    • Hardware
      Accessori
      • piCamera
        • piCamera
          Sorveglianza
        • piCamera
          Text on Video
        • piCamera
          Filtri Effetto
        • piCamera
          Canon & Nikon

Articolo introduttivo di una serie di articoli che tratteranno via via in maniera sempre più approfondita l’affascinante mondo dell’analisi delle immagini. E lo faremo in Python.

La PiCamera v2

PiCamera v2 (vedi qui), uscita nell’Aprile 2016, è la nuova versione di questo modulo che è andato a sostituire l’ormai vecchio modello. Rimane compatibile con tutti i modelli di Raspberry esistenti. Infatti il flat cable è rimasto immutato, adatto ancora per essere inserito nel connettore dedicato presente sul lato superiore di tutte le schede Raspberry.

Questo nuovo modulo monta una videocamera  Sony IMX219 da 8-megapixel che è andata a sostituire la OmniVision OC5647 da 5-megapixel presente sul modello precedente.

PiCamera V1.3 e V2.1 messe a confronto
piCamera

Articolo suggerito:

piCamera 8Mp

Installare la PiCamera

La PiCamera essendo un modulo progettato per essere utilizzato su Raspberry ha una sua porta dedicata sulla scheda. Quindi inserite, a Pi spento (mi raccomando), il flat cable facendo attenzione che il lato blu sia rivolto verso la porta Ethernet. Una volta connessa la WebCam accendete il Raspberry Pi.

meccanismo-complesso-picamera-2

Accendete la scheda. Una volta che il sistema Raspbian si sarà attivato, collegatevi ad una sessione al terminale e immettete il comando per la configurazione.

$ sudo raspi-config

Nel menu che appare, selezionate la voce Enable Camera, e successivamente selezionate Enable. Selezionate Finish e poi premete Yes per il reboot.

meccanismo-complesso-raspi-config-picamera

Attendete il riavvio della scheda. Poi testiamo se la PiCamera funziona correttamete. Apriamo di nuovo una console di comando e immettiamo il seguente comando:

raspistill -o image.jpg

Sullo schermo dovrebbe apparire una preview di pochi secondi e poi catturare l’immagine.

Utilizzare la PiCamera con Python

Esiste un modulo in Python per utilizzare la PiCamera con il linguaggio Python: python-picamera. Questo modulo è stato sviluppato da Dave Jones ( vedi qui). Grazie a questa libreria sarà possibile scrivere dei programmi che ci permettano di scattare immagini, girare filmati per poi elaborarli successivamente. Inoltre grazie ai pin GPIO sarà possibile integrare l’uso della telecamera con sensori o interruttori

Quindi per poter programmare in Python con la PiCamera installiamo i moduli necessari:

$ sudo apt-get install python-picamera python3-picamera python-rpi.gpio

Una volta installati tutti i moduli siamo pronti per testare la nostra PiCamera con il linguaggio Python. Creiamo un nuovo file e salviamolo come get_image.py ( mi raccomando non salvatelo come picamera.py 😉 )

$ nano get_image.py

Poi per prima cosa importiamo la classe PiCamera, questa corrisponderà alla nostra WebCam su cui referenzieremo direttamente i comandi. Importiamo anche time checi servirà in seguito per la gestione dei tempi di attesa tra un comando ed il successivo.

from picamera import PiCamera
import time

Adesso possiamo mandare i comandi per l’acquisizione di un’immagine che verrà salvata sotto forma di file JPG direttamente nel file system.

camera = PiCamera() 

camera.start_preview()
time.sleep(10)
camera.capture('/home/pi/image.jpg')
camera.stop_preview()

Salvate il programma con CTRL+O e poi uscite CTRL+X. Poi eseguitelo

$ python get_image

Dovrebbe apparire il preview della WebCam, attendere 10 secondi e poi scattare l’immagine, per poi chiudersi. I secondi di attesa sono necessari per dare tempo al sensore di impostare i livelli di luce, prima di scattare una foto.

meccanismo-complesso-picamera

Se durante il preview dovreste ottenere una foto ribaltata, cioè sotto sopra, non c’è bisogno di ribaltare la PiCamera, ma introdurre il comando

camera.rotation = 180

prima della funzione start_preview().

Adesso che abbiamo visto che la PiCamera funziona correttamente ed è possibile utilizzarla con Python, vediamo alcune semplici operazioni che ci possono tornare utili per migliorare il nostro approccio con questa WebCam.

Scattare più foto in sequenza

Partiamo dall’esempio precedente, e modificandolo potremo ottenere una sequenza di foto. Per esempio se vogliamo scattare una sequenza di 9 foto possiamo scrivere il codice precedente inserendolo all’interno di un loop.

from picamera import PiCamera
import time

camera.start_preview()
for i in range(9):
    time.sleep(5)
    camera.capture('/home/pi/image%s.jpg' % i)
camera.stop_preview()

Dallo script precedente è facile vedere come si possa aggiungere un numero alla fine del file, per evitare che l’immagine JPG venga sovrascritta.

Adesso sarebbe interessante prendere tutte queste foto e farne un filmato! Possiamo utilizzare avconv. Se non fosse presente sul vostro raspberry è possibile installarlo con i seguenti comandi:

$ sudo apt-get install libavcodec-extra
$ sudo apt-get install libav-tools

Una volta installati i codec e avconc (all’interno di libav-tools). Possiamo cominciare a creare il video con la sequenza di immagini (stop motion video).

$ avconv -r 10 -i image%d.jpg animation.mp4

Otterete un filmato chiamato animation.mp4.

Scattare una foto premendo un pulsante

Abbiamo detto in precedenza che uno degli aspetti più interessanti dell’utilizzo della PiCamera è la possibilità di poterla gestire attraverso sensori e interruttori tramite i pin GPIO. L’esempio più semplice per avere un’idea della cosa è quella di scattare una foto alla pressione di un pulsante.

Per prima cosa sarà necessario collegare un pulsante alla scheda seguendo lo schema rappresentato qui di seguito. Quindi utilizzeremo due jumper wire e un pulsante che andremo a posizionare su una breadboard.

meccanismo-complesso-picamera-fritzing

Una volta preparato questo semplice circuito, apriamo un file editor, come per esempio nano, e creiamo un file dove riporterai il codice seguente. Per prima cosa importiamo i moduli necessari

import time
import picamera
import Rpi.GPIO as GPIO

poi impostiamo i pin GPIO, in particolare  il PIN 17 che verrà settato come input in pull-up.

GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

infine gli ultimi comandi attiveranno la WebCam, e quando il pin rivelerà un edge in caduta, provocato dalla pressione del pulsante direttamente collegato ad esso, un’immagine verrà acquisita e salvata come JPG.

camera = PiCamera()
camera.start_preview()
GPIO.wait_for_edge(17, GPIO.FALLING)
camera.capture('/home/pi/image.jpg')
camera.stop_preview()

Salva lo script in un file ed eseguilo. Un file image.jpg verrà salvato sul tuo file system, in cui ci sarà la foto scattata dalla WebCam nel momento preciso in cui hai premuto il pulsante.

Articolo suggerito:

Raspberry Pi 4 Screen 4.3′

Registrare un video

Ma la PiCamera non è in grado solo di scattare delle foto, ma di registrare dei veri e propri filmati. Quindi grazie a Python possiamo acquisire un video da visualizzare in seguito, e questa operazione è molto semplice e non si discosta molto dall’acquisizione di semplici immagini.

Apriamo un nuovo file chiamandolo get_movie.py

$ nano get_movie.py

importiamo ancora i moduli necessari per utilizzare la PiCamera. Poi definiamo la PiCamera.

from picamera import PiCamera 
import time 

camera = PiCamera()

Il codice che segue è davvero molto semplice ed intuibile.

camera.start_preview()
camera.start_recording('/home/pi/video.h264')
time.sleep(10)
camera.stop_recording()
camera.stop_preview()

Eseguite lo script

$ sudo python get_movie.py

Dopo aver eseguito questo script, avrete un nuovo file video.h264 con il video registrato nei 10 secondi. Per poterlo visualizzare potete utilizzare omxplayer.

$ omxplayer video.h264

Se omxplayer non fosse presente potete installarlo con il comando

$ sudo apt-get install omxplayer

Se per esempio volete visualizzare il video su un altro sistema operativo (Windows) è necessario convertire il formato h.264 in un formato più comune come MP4. Questo lo puoi fare con avconv, lanciando il seguendo comando:

$ avconv -i video.h264 -c:v libx264 video.mp4

Oppure potete utilizzare quest’altra applicazione chiamata GPAC, molto veloce.

$ sudo apt-get install -y gpac

E poi lanciare la conversione

$ MP4Box -fps 30 -add video.h264 video.mp4

Conclusione

Questo articolo è una breve panoramica sull’utilizzo della PiCamera, un bellissimo modulo da aggiungere alla scheda Raspberry. Nei prossimi articoli scopriremo come utilizzare la PiCamera per effettuare delle operazioni più complesse programmando in Python. Effettueremo analisi di immagini attraverso l’uso della libreria OpenVC.

18 commenti su “PiCamera & Python – programmiamo la webcam su Raspberry Pi

  1. Beniamino Feula

    Scattare una foto premendo un pulsante:
    Vorrei scattare attraverso l’ottica di una macchina normale o reflex e per questo mi servirebbe un “modulo-camera” senza ottica
    chiedo se è possibile elencarmi con N° e modello dei componenti da reperire

    Grazie

      • Beniamino Feula

        Grazie per tutte le informazioni datemi
        adesso ho ripreso un po ad interessarmi di nuovo se faccio passi avanti lo pubblico
        di nuovo grazie …

        • Beniamino Feula

          Buongiorno e saluto
          Questo è lo scrip dello scatto una foto: salvato in py

          #!/urs/bin/env python
          #-*- coding:utf8 -*-

          import time
          import PiCamera
          import Rpi.GPIO as GPIO

          GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

          camera = PiCamera()
          camera.start_preview()
          GPIO.wait_for_edge(17, GPIO.FALLING)
          camera.capture(‘/home/pi/image.jpg’)
          camera.stop_preview()
          ———————————————————————–
          mi restituisce così:
          pi@raspberrypi:~ $ python scatto-foto.py
          File “scatto-foto.py”, line 8
          GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)
          ^
          SyntaxError: invalid syntax

          dove sbaglio?

          ————
          GRAZIE

          • admin

            Hai messo due funzioni sulla stessa riga.
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

          • Beniamino Feula

            Buona giornata Рnon riesco in nessun modo a farlo funzionare Рquesto ̬ lo script:

            #! /usr/bin/python

            import time
            import PiCamera
            import Rpi.GPIO as GPIO

            GPIO.setmode(GPIO.BCM)
            GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

            camera = PiCamera()
            camera.start_preview()
            GPIO.wait_for_edge(17, GPIO.FALLING)
            camera.capture(‘/home/pi/image.jpg’)
            camera.stop_preview()

            mi restituisce:
            pi@raspberrypi:~ $ /home/pi/scatto.py
            bash: /home/pi/scatto.py: /usr/bin/python^M: interprete errato: File o directory non esistente

          • Beniamino Feula

            nome file- scatto.py

            CODICE:

            #!/usr/bin/env python
            import time
            import PiCamera
            import Rpi.GPIO as GPIO

            GPIO.setmode(GPIO.BCM)
            GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

            camera = PiCamera()
            camera.start_preview()
            GPIO.wait_for_edge(17, GPIO.FALLING)
            camera.capture(‘/home/pi/image.jpg’)
            camera.stop_preview()
            ————————————————————————————————-
            mi restituisce così:
            pi@raspberrypi:~ $ /home/pi/scatto.py
            : File o directory non esistente
            —————————-
            GRAZIE

          • Beniamino Feula

            Buongiorno lanciando con questo comando lo script pubblicato il 21/03/2017:

            sudo python scatto.py

            Mi restituisce:
            pi@raspberrypi:~ $ sudo python scatto.py
            Traceback (most recent call last):
            File “scatto.py”, line 3, in
            import PiCamera
            ImportError: No module named PiCamera

            Grazie

          • admin

            Ciao Beniamino.
            Il nome del modulo in Python è picamera e non PiCamera.

          • Beniamino Feula

            pi@raspberrypi:~ $ /home/pi/scatto.py
            : File o directory non esistente
            pi@raspberrypi:~ $ sudo python scatto.py
            Traceback (most recent call last):
            File “scatto.py”, line 9, in
            camera = PiCamera()
            NameError: name ‘PiCamera’ is not defined

            da questi due comandi mi restituisce ^^^^^^^^^

            questo è il codice discatto.py

            #!/usr/bin/env python
            import time
            import picamera
            import RPi.GPIO as GPIO

            GPIO.setmode(GPIO.BCM)
            GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

            camera = PiCamera()
            camera.start_preview()
            GPIO.wait_for_edge(17, GPIO.FALLING)
            camera.capture(‘/home/pi/image.jpg’)
            camera.stop_preview()

            GRAZIE

          • Beniamino Feula

            Questo mi funziona perfettamente :
            Scattare più foto in sequenza
            ——
            NON RIESCO CON QUESTO:
            Scattare una foto premendo un pulsante

            c’è qualcuno che mi può dare lo script funzionante?
            GRAZIE

  2. Titanic4wd

    Ciao .. articolo interessante ..
    io non conosco molto ne la scheda ne la programmazione , ma vorrei realizzare un progetto e vorrei sapere visto la vostra esperienza se e’ fattibile.
    Vorrei riprendere con la telecamera e mostrare su un piccolo schermo le riprese.
    E questo non penso sia difficile .. ma dopo vorrei poter tramite una app del telefono aumentare e diminuire sia il contrasto che la luminosita.. percio’ tutto quello che verra’ ripresodve essere convertito… ultima cosa fare lo zoom e rimappare i colori .. il rosse deve diventare giallo ecc..ecc..
    e’ fattibile con Raspberry 3 ? non devo salvare il video ..
    Grazie

    • admin

      Tutto il resto è possibile, eccetto lo zoom. Infatti l’ottica montata sulla PiCamera non possiede zoom. (parliamo di zoom ottico), come del resto tutte le camere montate sui cellulari. Per quanto riguarda lo zoom digitale (finto, è solo un ingrandimento dell’immagine con relativa perdita di risoluzione), invece si. Se vuoi fare degli zoom realistici devi collegare il Raspberry ad una videocamera dotata di ottica mobile (zoom) ma i prezzi sono notevolmente maggiori. Per quanto riguarda l’app dal telefono, questa lavorerà direttamente sul formato video acquisito e quindi potrai fare tutte le operazioni che desideri (rimappatura dei colori, regolazione luminosità e contrasti). Se invece intendi un controllo remoto dal cellulare alla PiCamera per controllare questi valori in tempo reale (durante l’acquisizione video) anche questo è possibile (potresti utilizzarlo per regolare in tempo reale questi valori).

    • admin

      Ciao lood,
      puoi aggiungere tutti i formati che vuoi al nome del file, lavorando sulla stringa corrispondente. Per quanto riguarda l’aggiunta del tempo e l’ora corrente ecco un po di esempi:

      import datetime
      i = datetime.datetime.now()
      print (“Data e ora corrente = %s” % i)
      print (“Data e ora ISO format = %s” % i.isoformat())
      print (“Anno corrente = %s” %i.year)
      print (“Mese corrente = %s” %i.month)
      print (“Data corrente (giorno) = %s” %i.day)
      print (“Formato dd/mm/yyyy = %s/%s/%s” % (i.day, i.month, i.year))
      print (“Ora corrente = %s” %i.hour)
      print (“Minuto corrente = %s” %i.minute)
      print (“Secondo corrente = %s” %i.second)
      print (“Formato hh:mm:ss = %s:%s:%s” % (i.hour, i.minute, i.second))

  3. rbergo

    Buongiorno,
    ho trovato questo articolo molto interessante e vorrei approfondire un aspetto che riguarda il tempo di esecuzione di uno scatto fotografico.

    Premetto che non ho ancora sperimentato nulla ma, dovendo pensare ad una applicazione che scatta fotografie, tutte alla stessa condizione di luminosità, con un trigger a 500ms, vorrei chiedervi:
    1) qual’è il tempo necessario ad eseguire uno scatto e a memorizzarlo su di un file,
    2) qual’è il numero massimo di scatti per ogni secondo.

    Grazie!

  4. welby

    ciao
    se volessi inviare l’immagine per e mail invece di salvarla ?
    o se la volessi inviare con ftp
    Logicamente implementando lo script get_image
    Come si può fare?
    Grazie

    • webmaster

      Importi

      import smtplib

      e poi implementi all’interno della funzione, la creazione dell’oggetto mail, gli assegni un allegato e lo invii all’indirizzo da te desiderato.

Lascia un commento