22 giugno 2017

tutorial: come video-sorvegliare con il raspberry pi zero (wireless)


Benvenuti!
Questo tutorial vi aiuterà ad apprendere le basi per costruire un sistema di video-sorveglianza con l'ausilio di un raspberry pi zero o zero wireless (qui trovate tutti i miei focus su questi dispositivi) e la pi camera.

Nota: il presente articolo contiene una infarinatura generale, i codici richiesti per il funzionamento ed un esempio d'uso ben preciso. Gli utilizzi, però, possono spaziare tra tantissime alternative, e soprattutto può essere perfezionato e reso molto più affidabile ed efficace! Se avete proposte al riguardo o volete approfondire, non esitate a lasciare un commento o a contattarmi sui canali social.

Prima di addentrarci, vi riporto il video di supporto a questa guida che ho pubblicato sul mio canale YouTube:


Inoltre vi segnalo che nella pagina dedicata troverete tutti i tutorial da me pubblicati.


1. l'attrezzatura minima per iniziare


Per costruire un impianto di video-sorveglianza occorrono:
  • un raspberry pi zero wireless (o un qualsiasi altro raspberry pi) + una microSD + un alimentatore o un powerbank (da almeno 2A) + una o più pi camera
  • un PC o smartphone o tablet
  • Raspbian OS
  • una connessione ad internet + un router (se utilizzerete il pi zero vi sarà necessario anche un dongle Wi-Fi o adattatore LAN per la connessione alla rete)

Per quanto riguarda il primo punto non occorre altro: utilizzeremo il raspberry pi zero sempre da remoto, quindi non sarà necessario utilizzare alcuna periferica collegata al pi. Sarà invece indispensabile avere un alimentatore che eroghi in uscita almeno 2A.
Per l'utilizzo finale del progettino ci collegheremo da remoto al raspberry pi via browser del PC, smartphone o tablet.
Serve commentare il quarto punto (=D)?



2. la configurazione iniziale del raspberry pi e della camera


L'idea alla base è quella di realizzare un sistema formato da una o più videocamere poste dove a voi necessario e che possano essere controllate da remoto. Questo progetto è una base di partenza e potrà essere potenziato e migliorato in tantissimi modi, ma lo scopo di questa guida è capire quali siano le componenti basilari per costruire un sistema di sorveglianza remota.

Il fulcro di tutto è la pi camera, la camera ufficiale della raspberry pi foundation per i suoi single board computer: ne esistono di vari tipi e revisioni, e sono state prodotte anche camere non ufficiali ma perfettamente compatibili. Quello utilizzato in questo tutorial è il modello ufficiale da 8 megapixel nella sua ultima incarnazione; ne esiste anche una versione più vecchia da 5 megapixel nonché quella senza filtro IR che è consigliata per l'uso al buio.
Come anticipato può essere utilizzato un qualsiasi raspberry pi, ma io ho deciso di impiegare il pi zero wireless principalmente per 2 motivi: rispetto al pi 3 esso è decisamente più compatto e meno "invasivo" se posizionato in giro per casa, e poi perché rispetto al pi zero "standard" esso ha già integrato il Wi-Fi che permetterà l'accesso da remoto alla videocamera.

A post shared by geek o NERD ? (@geekonerd) on

Inoltre, il case ufficiale del pi zero wireless ha un coperchio predisposto appositamente per ospitare la pi camera, ed in confezione è anche compreso il cavo compatibile con la dimensione ridotta della camera port presente sui pi zero. Collegare questo cavo è cosa banale: una volta sfilato -delicatamente- il cavo originale della pi camera e sostituito con quello compatibile con il pi zero, rimane soltanto il compito di collegare l'altra estremità nel pi zero stesso ed incastrare la pi camera nello spazio a lei predisposto nel coperchio. Completati questi tre semplicissimi passaggi la pi camera sarà collegata saldamente al piccolo single board computer.

A questo punto per poter utilizzare la pi camera conviene utilizzare Raspbian OS il quale contiene tutte le librerie già al suo interno (o facilmente reperibili dai repository). Il passaggio fondamentale da compiere per poter abilitare l'accesso alla camera è quello di abilitare l'interfaccia Camera nel tool di configurazione raspberry pi (raspi-config da terminale, "Preferences » Raspberry Pi Configuration" da interfaccia).
Una volta riavviato il sistema, la camera sarà pronta per scattare foto o registrare video e così via: il modo più facile per utilizzare la pi camera è -ovviamente- scrivendo codice python poiché la fondazione inglese fornisce le librerie di controllo già pronte all'uso scritte proprio in questo linguaggio e in rete si trova tanto materiale in merito. Comunque la documentazione ufficiale la trovate qui.


Ovviamente accedere alla camera dal raspberry pi stesso serve a poco o a niente, soprattutto nel caso specifico del progetto che stiamo realizzando. L'idea è quella di poter controllare da remoto, quindi dal nostro PC o dal tablet oppure dallo smartphone, ciò che la camera sta riprendendo.

E proprio per raggiungere tale scopo ho realizzato una piccola web-application sulla falsariga di quella che realizzai per il tutorial su come controllare da remoto le prese di casa con il raspberry pi zero wireless, che va installata sul pi zero e che permetterà di controllare la pi camera dall'esterno.

L'applicazione richiede l'installazione di alcuni pacchetti dai repository di Raspbian OS ed il software che, come mio solito, ho caricato su github:
  • collegatevi in SSH al raspberry pi dal vostro PC (per maggiori dettagli rimando al tutorial su come creare un server web in casa con il raspberry pi 3)
  • assicuratevi di avere il sistema aggiornato all'ultima versione con il comando sudo apt-get update e poi sudo apt-get upgrade && sudo apt-get dist-upgrade
  • installate Apache + PHP con il comando sudo apt-get install apache2 libapache2-mod-php5
  • recatevi nella root del web server con il comando cd /var/www/html
  • assicuratevi di avere tutte le librerie della pi camera installate sul sistema (nelle ultime versioni di Raspbian OS sono sicuramente già comprese) con il comando sudo apt-get install python-picamera python3-picamera
  • clonate il repository github con il codice della mia web-app tramite il comando sudo git clone https://github.com/geekonerd/securpeye.git
  • eseguite i seguenti passi:
    • sudo chown -R pi:pi securpeye
    • cd securpeye
    • chmod 666 data/data.json
    • chmod -R 666 data/snaps
    • sudo cp /etc/sudoers.d/010_pi-nopasswd /etc/sudoers.d/011_wwwdata-nopasswd
    • sudo vim.tiny /etc/sudoers.d/011_wwwdata-nopasswd
    • modificate l'utente "pi" con "www-data" (premendo "i" per iniziare a digitare, quindi ESC una volta sostituito l'utente, e poi ":wq!" per salvare ed uscire)
  • riavviate Raspbian OS con il comando sudo reboot 0

A questo punto avrete la web-application pronta all'uso e la pi camera in attesa di comandi.


3. usare la pi camera


Come funziona e cosa permette di fare la web-app secur[P]EYE? Tanto per cominciare potrete accedervi digitando sul browser web del vostro PC, smartphone o tablet l'indirizzo IP assegnato al raspberry pi seguito dal nome della web-app (es. http://192.168.1.6/securpeye).

L'applicazione è una sorta di plancia di comando da cui avviare, interrompere e controllare tutte le camere configurate.
Di base la configurazione prevede una sola camera e l'aggiunta di ulteriori camere va fatta modificando i file di configurazione (config.php e data.json): magari un giorno potrà diventare un tool completamente modificabile da interfaccia utente... Tre cose, però, sono già gestibili da UI: dare un nome alla specifica camera, indicare l'indirizzo IP della stessa, ed impostare la durata in secondi della registrazione video.

Nota: se decideste di aggiungere più camere dovrete effettuare tutti i passaggi descritti al punto 2 di questa guida su ogni raspberry pi + pi camera: il mio consiglio è di fare in modo che la cartella "data" sia condivisa tra tutti i pi (es. rendendola una cartella di rete) in modo da avere le configurazioni in comune ed evitare di ripeterle ogni volta. Inoltre è probabile che dobbiate abilitare il cross-origin resource sharing (CORS) per ogni Apache affinché la web-app possa ricevere dati dalle camere. In alternativa potete semplicemente tenere tutte le istanze separate e collegarvi ad ogni camera in modo individuale tramite l'indirizzo IP assegnato ad ogni raspberry pi.

Una volta configurato il vostro ambiente, potrete attivare e controllare la camera di interesse, oppure accedere all'archivio di tutte le foto e video precedentemente catturati. Ribadisco nuovamente che questo progettino è poco più di una demo ed una base su cui potenzialmente costruire un sistema più complesso.
Attivando la camera viene lanciato lo streaming video con l'output di ciò che la pi camera sta riprendendo; sarà poi possibile decidere se interrompere la ripresa, registrare un video per il numero di secondi desiderato oppure scattare una foto.

Nota: poiché la pi camera non può essere controllata da più processi in simultanea (infatti si dà per scontato che sia sempre una ed una soltanto l'azione in esecuzione), scattando una foto o avviando la registrazione video, lo streaming dovrà necessariamente essere bloccato e l'utente dovrà poi riattivarlo manualmente al termine del processo di cattura.


Aldilà dei limiti volutamente presenti in questo progetto, ciò su cui è importante ed interessante soffermarsi è come funziona lo streaming video dal pi. Il codice python che vi ho fornito non fa altro che sfruttare il modulo http.server nativo del linguaggio per tirar su un piccolo streaming server con il quale stremmare l'output della camera utilizzando il formato mjpeg.

Di seguito le parti salienti del codice (activate.py) che tira su il server e manda in output il filmato con risoluzione 640x480 @ 24 fps:

import io
import picamera
import logging
import socketserver
from threading import Condition
from http import server
[...]
class StreamingHandler(server.BaseHTTPRequestHandler):
    def do_GET(self):
        [...]
        elif self.path == '/stream.mjpg':
            [...]
            try:
                while True:
                    with output.condition:
                        output.condition.wait()
                        frame = output.frame
                    self.wfile.write(b'--FRAME\r\n')
                    self.send_header('Content-Type', 'image/jpeg')
                    self.send_header('Content-Length', len(frame))
                    self.end_headers()
                    self.wfile.write(frame)
                    self.wfile.write(b'\r\n')
        [...]
[...]
with picamera.PiCamera(resolution='640x480', framerate=24) as camera:
    output = StreamingOutput()
    camera.start_recording(output, format='mjpeg')
    try:
        address = ('', 8000)
        server = StreamingServer(address, StreamingHandler)
        server.serve_forever()
    finally:
        camera.stop_recording()


Esistono sicuramente soluzioni più raffinate ma che vanno oltre gli scopi di questo tutorial: una alternativa è la libreria pistreaming che tira su un piccolo streaming server a bassa latenza il quale può anche accettare più connessioni in contemporanea (per lo meno finché la banda a disposizione del raspberry pi riesce a stargli dietro). Personalmente non mi ha convito al 100% e quindi alla fine ho preferito impiegare la modalità basilare che fa il suo dovere senza troppi fronzoli.

La cattura dei video e delle foto è, invece, decisamente più semplice e bastano davvero poche righe di codice per effettuarle (record.py e snap.py). Ad esempio:

from picamera import PiCamera  ## importa picamera library
camera = PiCamera()  ## nuovo oggetto camera
camera.resolution = (1024, 768)  ## imposta risoluzione

camera.capture('foo.jpg')  ## cattura foto e salva sul file foo.jpg

camera.start_recording('my_video.h264')  ## registra video sul file my_video.h264
camera.wait_recording(60)  ## registra per 60 secondi
camera.stop_recording()  ## termina registrazione


Per tutta la lista dei comandi a disposizione e per vari esempi d'uso rimando alla documentazione ufficiale.


4. conclusioni e ultime note


L'approccio che abbiamo visto può essere sicuramente perfezionato ad esempio migliorando la gestione del passaggio tra streaming a cattura foto/video e viceversa, oppure aggiungendo delle informazioni testuali (es. data e ora dello scatto) sulle catture effettuate, eccetera; ma soprattutto si potrebbero utilizzare librerie molto più complesse e potenti ad esempio per fare riconoscimento di volti od oggetti (anche in movimento), oppure avviare automaticamente la registrazione allo scatenarsi di un particolare evento, o ancora creare un sistema di notifica nel qual caso la camera rilevi un determinato evento, e così via. Sono tutti esempi di funzionalità avanzate che se siete interessati potremmo indagare in modo più approfondito in futuri focus.

Nota: visto che la web-application così strutturata è fondamentalmente una demo, essa può essere utilizzata senza problemi in casa (o ovunque vogliate) sotto rete intranet / locale. Personalmente ne sconsiglio l'utilizzo via internet perché il tutto non è ottimizzato e non viene fornita alcuna garanzia di sicurezza sui dati che trasmessi.


Bene: come indicato ad inizio guida, alcuni aspetti sono stati appositamente lasciati in secondo piano, ma se siete interessati ad approfondirli non esitate a contattarmi nei commenti di questo tutorial o del video ad esso correlato, oppure sui canali social!

Spero che la guida vi sia stata utile. Al prossimo tutorial!

Nessun commento:

Posta un commento