Non ci sono prodotti a carrello.
Realizziamo con Raspberry Pi un sistema in grado di rilevare il movimento di persone e oggetti tramite una videocamera e di inviare e-mail di allarme.
La cosiddetta Computer Vision o visione artificiale, รจ un settore di ricerca che si occupa di come i computer possano interpretare la realtร visiva esattamente come un essere umano; essa si avvale di algoritmi complessi in grado di elaborare immagini fisse o in movimento, al fine di fornire indicazioni e informazioni su persone e oggetti, proprio come farebbe il nostro sistema percettivo.
Dal punto di vista pratico, la visione artificiale elaborata da un computer cerca di automatizzare quelle attivitร che il sistema visivo umano svolge naturalmente. I campi applicativi della Computer Vision vanno dalla digitalizzazione ambientale, la ricostruzione virtuale di luoghi e scenari, fino al riconoscimento e il monitoraggio visivo degli oggetti e delle persone.
Lโacquisizione delle immagini e lโelaborazione delle informazioni visive in tempo reale necessitano solitamente di dispositivi ottici ad alta risoluzione, di potenti computer e software ad hoc.
In questo articolo esporremo unโapplicazione di OpenCV 4, ossia la release piรน recente della diffusa libreria libera, rilasciata sotto una licenza BSD (Berkeley Software Distribution), che permette di sviluppare applicazioni di visione artificiale anche molto complesse.
La libreria OpenCV 4
Dal sito ufficiale di OpenCV vediamo innanzitutto le caratteristiche salienti.
โข OpenCV รจ ora una libreria C++ 11 e richiede un compilatore conforme a C++ 11. La versione CMake minima richiesta รจ stata portata a 3.5.1.
โข Molte API C di OpenCV 1.x sono state rimosse.
โข La persistenza (la memorizzazione e il caricamento dei dati strutturati da/a XML, YAML o JSON) nel modulo principale รจ stata completamente reimplementata in C++ 11 e ha perso anche le API in C.
โข ร stato aggiunto il nuovo modulo G-API, che funge da motore per pipeline di elaborazione molto efficiente per immagini basate su grafici.
โข Il modulo dnn รจ stato aggiornato con Deep Learning Deployment Toolkit dal toolkit OpenVINO ™ R4. Consultare la guida su come costruire e utilizzare OpenCV con il supporto DLDT.
โข Il modulo dnn ora include il backend Vulkan sperimentale e supporta le reti in formato ONNX.
โข Il famoso algoritmo Kinect Fusion รจ stato implementato e ottimizzato per CPU e GPU (OpenCL).
โข Un rilevatore e decodificatore di codice QR sono stati aggiunti al modulo objdetect
โข Lโalgoritmo di flusso ottico denso DIS ad alta efficienza รจ stato spostato da opencv_contrib al modulo video.
โข Maggiori dettagli possono essere trovati negli annunci delle versioni precedenti: 4.0-alpha, 4.0-beta, 4.0-rc e nel changelog.
Ricordiamo che OpenCV รจ disponibile per interfacce C++, Python e Java e supporta le piattaforme Windows, Linux, Mac OS, iOS e Android. Per il nostro progetto verrร utilizzata la versione Linux/Ubuntu ottimizzata per Raspberry Pi 3B+ e interfaccia Python 3.
La scelta di sviluppare un progetto di home automation con OpenCV e la scheda Raspberry Pi si basa su due semplici motivi: il primo รจ legato alla compattezza del microcomputer, che puรฒ essere tranquillamente alloggiato in un piccolo contenitore, magari stampato in casa con la stampante 3D, il secondo รจ legato alla presenza della porta GPIO di Raspberry Pi a cui possiamo collegare facilmente dispositivi di controllo e di allarme.
Aggiungiamo infine la facilitร di sviluppare in ambiente Python, che รจ giร integrato nel suo sistema operativo.
VNC Viewer
Anche se si puรฒ operare direttamente con un mouse, una tastiera e un monitor HDMI, collegati alla scheda Raspberry Pi, di solito si preferisce creare un collegamento al desktop di Raspbian attraverso una connessione SSH o VNC.
In questo modo, dopo aver configurato la rete Wi-Fi o Ethernet di Raspberry Pi, si puรฒ accedere al desktop remoto utilizzando uno dei tanti terminali SSH oppure tramite il comodo VNC Viewer, scaricabile gratuitamente dal sito ufficiale e disponibile per tutte le piattaforme. Per la cronaca, abbiamo usato la versione per PC Windows, ma lโutilizzo รจ identico anche per tutti gli altri OS.
Configurazione delle interfacce di Raspberry Pi
Prima di configurare la connessione VNC รจ necessario attivare lโinterfaccia VNC dal menu Preferenze > Raspberry Pi Configuration di Raspbian, come illustrato in Fig. 1.
Per fare questo, una volta aperta la finestra Raspberry Pi Configuration, basta fare clic sulla voce VNC. Nella stessa finestra si possono attivare anche tutte le altre interfacce, compresa lโinterfaccia Camera, come illustrato in Fig. 2.
Le altre interfacce, anche se non servono per questo progetto, potranno venire utili in futuro.
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-1-3-1.jpg)
Fig. 1 Il menu Preferenze > Raspberry Pi Configuration di Raspbian
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-2-4.jpg)
Fig. 2 La finestra Raspberry Pi Configuration con le interfacce tutte attivate
Per usare la connessione VNC bisogna conoscere lโindirizzo IP che รจ stato assegnato automaticamente alla scheda al momento della prima configurazione WLAN o LAN. Se si vuole sfruttare la rete Wi-Fi della scheda รจ sufficiente aprire la finestra Network Preferences (Fig. 3) in cui รจ visibile lโindirizzo assegnato dalla connessione WLAN.
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-3-3.jpg)
Fig. 3 La finestra Network Preferences
Connessione VNC
Per creare una nuova connessione con VNC Viewer, basta inserire nella finestra Properties lโindirizzo IP della scheda Raspberry Pi, come illustrato in Fig. 4.
Una volta avviata la connessione VNC verrร chiesto il nome utente e la password di autenticazione che, per default, sono rispettivamente โpiโ e โraspberryโ (Fig. 5).
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-4-3.jpg)
Fig. 4 La finestra Properties di VNC Viewer
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-5-3.jpg)
Fig. 5 La finestra Authentication di VNC Viewer
Una volta effettuata la connessione, il desktop di Raspbian sarร visibile a tutto schermo sul monitor del PC. Da questo momento in poi, si potranno scollegare il mouse, la tastiera e il monitor dalla scheda Raspberry Pi e avere il controllo totale da remoto. Puรฒ capitare che lโindirizzo IP assegnato dal DHCP cambi, quindi รจ consigliabile configurare un IP statico nella scheda Raspberry Pi.
Configurare un IP statico su Raspberry Pi
Per configurare un IP statico รจ sufficiente aprire una finestra del terminale (Fig. 6) e digitare il seguente comando:
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-6-3.jpg)
Fig. 6 La finestra dellโeditor nano in cui modificare il file dhcpcd.conf
sudo nano /etc/dhcpcd.conf
Questo aprirร il file dhcpcd.conf nella finestra dellโeditor nano.
Nellโesempio riportato nel file dhcpcd.conf , basta quindi decommentare le seguenti righe e modificare i dati in base alla propria rete e allโindirizzo IP che si vuole usare per la connessione remota:
interface wlan0
#oppure eth0 se si usa una rete LAN
static ip_address=192.168.1.100/24
#un qualsiasi indirizzo nel segmento di rete del proprio router
static routers=192.168.1.1
#indirizzo IP del router
static domain_name_servers=192.168.1.1 8.8.8.8
#indirizzi statici dei server
Una volta salvato il file e riavviato il sistema, lโIP statico cosรฌ impostato permetterร di effettuare la connessione VNC utilizzando sempre lo stesso indirizzo.
Raspberry Pi 3B+ e Camera Module v2
Per questo progetto abbiamo optato per la scheda Raspberry Pi modello 3B+ e per Raspberry Pi Camera Module v2. La versione 2 della videocamera offre una risoluzione di ben 8 Megapixel e 3.820 x 2.464 pixel di risoluzione del sensore.
La Camera Module v2 va collegata come illustrato in Fig. 7, usando il flat cable in dotazione e facendo attenzione al verso di inserimento alla porta CSI di Raspberry Pi 3 B+.
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-7-2.jpg)
Fig. 7 Collegamento del modulo Camera Module v2 a Raspberry Pi 3 B+
Test della videocamera
Per vedere se la videocamera funziona correttamente con Python, si consiglia di effettuare questo semplice test. In una nuova finestra dellโeditor di Python scrivere queste poche righe di codice:
from picamera import PiCamera from time import sleep camera = PiCamera() camera.start_preview() sleep(10) camera.stop_preview()
Allโavvio dello script dovrebbe aprirsi una finestra di preview e chiudersi dopo 10 secondi.
Se questo non accade, controllare che il flat cable sia ben inserito nel verso giusto nello slot. Se tutto funziona a dovere, si puรฒ proseguire tranquillamente allโinstallazione di OpenCV 4.
Installazione di OpenCV 4 su Raspbian Stretch
Come per le precedenti versioni, anche OpenCV 4 necessita di una particolare installazione. Per cui, se non si dispone del giร citato sistema operativo Raspbian Stretch, รจ necessario aggiornare il sistema operativo per sfruttare le nuove funzionalitร .
Attenzione! OpenCV 4 non รจ stato testato su versioni di Raspbian precedenti a Stretch.
Data la giovane etร di OpenCV 4, non abbiamo trovato molte guide on-line, per cui ci siamo affidati allโesperienza di Adrian Rosebrock che gestisce il suo blog sul Deep Learning allโindirizzo https://www.pyimagesearch.com e di Satya Mallick che gestisce il sito https://www.learnopencv.com dedicato alla Computer Vision a al Machine Learning. Entrambi riportano pressappoco la stessa procedura di installazione.
Notate che per molti comandi da terminale si deve usare il carattere tilde (~). Se non รจ presente sulla tastiera, usare i tasti SHIFT+CTRL+u e inserire il codice esadecimale 7e + INVIO.
Installare le dipendenze di OpenCV 4
Prima di avviare qualsiasi installazione su Raspbian รจ sempre consigliabile aggiornare i repository con il comando apt-get, aprendo una finestra del terminale:
sudo apt-get update && sudo apt-get upgrade
Quindi, sempre con apt-get, si devono installare tutti gli strumenti di sviluppo, inclusa lโultima versione di CMake:
sudo apt-get install build-essential cmake unzip pkg-config
Successivamente, installiamo una selezione di librerie per il trattamento delle immagini e del video:
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev sudo apt-get install libxvidcore-dev libx264-dev
Quindi, installiamo i toolkit GTK per lโinterfaccia grafica:
sudo apt-get install libgtk-3-dev sudo apt-get install libcanberra-gtk*
(lโasterisco acquisirร la specifica GTK ARM)
A questo punto servono due pacchetti che contengono ottimizzazioni numeriche per OpenCV:
sudo apt-get install libatlas-base-dev gfortran
Infine, installiamo gli strumenti di sviluppo per Python 3:
sudo apt-get install python3-dev
Dopo aver installato tutti i prerequisiti, รจ possibile eseguire il download di OpenCV 4.
Download di OpenCV 4
ร preferibile scaricare gli archivi di OpenCV4 nella cartella Home. Tutte le librerie di OpenCV 4 sono disponibili in due repository github chiamati opencv e opencv_contrib. Il repository contrib contiene moduli aggiuntivi creati dagli utenti.
Ecco i comandi da digitare per tornare alla cartella Home e scaricare i due repository.
cd ~ wget -O opencv.zip https://github.com/opencv/opencv/archive/4.0.0.zip wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.0.0.zip
Una volta scaricati gli archivi zip, vanno decompressi, sempre nella cartella Home:
unzip opencv.zip unzip opencv_contrib.zip
Verranno cosรฌ create le directory opencv-4.0.0 e opencv_contrib-4.0.0. Per motivi pratici si consiglia di rinominare le cartelle come opencv e opencv_contrib:
mv opencv-4.0.0 opencv mv opencv_contrib-4.0.0 opencv_contrib
A questo punto, prima della compilazione vera e propria della libreria OpenCV 4, รจ necessario predisporre lโambiente virtuale di Python 3.
Configurare lโambiente virtuale di Python 3
Se non si ha familiaritร con gli ambienti virtuali di Python e per sapere perchรฉ รจ consigliabile lavorare su un ambiente virtuale si veda il box dedicato.
Per prima cosa, bisogna installare pip:
wget https://bootstrap.pypa.io/get-pip.py sudo python3 get-pip.py
Quindi installiamo virtualenv e virtualenvwrapper che consentono di creare ambienti virtuali di Python 3:
sudo pip install virtualenv virtualenvwrapper sudo rm -rf ~/get-pip.py ~/.cache/pip
Per completare lโinstallazione di questi strumenti, รจ necessario aggiornare il file ~/.profile, usando questi semplici comandi echo:
echo โexport WORKON_HOME=$HOME/.virtualenvsโ >> ~/.profile echo โexport VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3โ >> ~/.profile echo โsource /usr/local/bin/virtualenvwrapper.shโ >> ~/.profile
Le aggiunte al profilo indicano il percorso della cartella di lavoro virtualenvs, creata dallo strumento virtualenv nella Home e il percorso dello script virtualwrapper che si trova nella cartella /usr/bin. Una volta aggiornato il profilo, basta attivarlo con il comando seguente:
source ~/.profile
Creare un ambiente virtuale per contenere OpenCV 4 e i pacchetti aggiuntivi
A questo punto si puรฒ creare un ambiente virtuale OpenCV 4 per Python 3 e lavorare cosรฌ in maniera indipendente da altri ambienti.
Questa linea di comando crea semplicemente un ambiente virtuale Python 3 chiamato โcvโ.
mkvirtualenv cv -p python3
Si puรฒ dare un nome qualsiasi allโambiente virtuale, ma si consiglia, per praticitร , di tenere un nome corto. Se il profilo รจ attivato correttamente e viene creato lโambiente virtuale โcvโ, si puรฒ verificare che siamo nellโambiente โcvโ usando il comando workon, come indicato dalla freccia di Fig. 8:
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-8-1.jpg)
Fig. 8 Attivazione del profilo e dellโambiente virtuale cv
workon cv
Installazione di NumPy
Il pacchetto Python richiesto da OpenCV 4 รจ NumPy. Per installarlo basta digitare il comando seguente:
pip install numpy
CMake e compilazione di OpenCV 4
Per compilare OpenCV 4, si userร CMake, seguito da make. Questo รจ il passo piรน dispendioso in termini di tempo. Innanzitutto, bisogna torna alla cartella opencv nella Home e creare al suo interno una sottodirectory build:
cd ~/opencv mkdir build cd build
A questo punto eseguite CMake per la creazione della build di tipo release.
ย cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \ -D ENABLE_NEON=ON \ -D ENABLE_VFPV3=ON \ -D BUILD_TESTS=OFF \ -D OPENCV_ENABLE_NONFREE=ON \ -D INSTALL_PYTHON_EXAMPLES=OFF \ -D BUILD_EXAMPLES=OFF ..
Notate che il carattere backslash serve a continuare il comando con un a capo. Notare anche la presenza del percorso per la compilazione dei moduli aggiuntivi opencv_contrib.
Aumentare lo SWAP sul Raspberry Pi
Prima di iniziare la compilazione vera e propria si consiglia di aumentare lo spazio di swap. Questo per evitare che la compilazione si interrompa a causa dellโesaurimento della memoria. Per fare ciรฒ basta modificare temporaneamente il file di swap che si trova in questo percorso /etc/dphys-swapfile:
sudo nano /etc/dphys-swapfile
… e quindi modificare la variabile CONF_SWAPSIZE portandola da 100 a 2.048 MB. Con il carattere # si commenta la riga:
# CONF_SWAPSIZE=100 CONF_SWAPSIZE=2048
Se non si esegue questo passaggio รจ molto probabile che la scheda si blocchi durante la compilazione. Una volta modificato il file di swap, bisogna fermare e riavviare il servizio di swap:
sudo /etc/init.d/dphys-swapfile stop sudo /etc/init.d/dphys-swapfile start
Compilazione di OpenCV 4
Ora tutto รจ pronto per compilare OpenCV 4. Digitare semplicemente il comando seguente:
make -j4
Si noti che lโopzione – j4 specifica lโuso di 4 core per la compilazione. Se si verificano errori di compilazione o la scheda si blocca, si puรฒ provare senza lโopzione -j4. Normalmente, il processo di compilazione di OpenCV 4 รจ abbastanza lungo e dispendioso di risorse, per cui si consiglia di prendersi una bella pausa e lasciare che la scheda lavori senza interventi esterni di nessun tipo, ovvero senza toccare mouse o tastiera. Al termine della compilazione, se tutto รจ andato bene si potrร vedere la percentuale di compilazione al 100% (Fig. 9).
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-9-1.png)
Fig. 9 Compilazione terminata con successo
Ora non ci resta che installare OpenCV 4 con due tipici comandi:
sudo make install sudo ldconfig
Non dimenticare di ripristinare lo swapfile, riportandolo a 100 MB, e riavviandolo:
sudo nano /etc/dphys-swapfile CONF_SWAPSIZE=2048 sudo /etc/init.d/dphys-swapfile stop sudo /etc/init.d/dphys-swapfile start
Collegamento simbolico di OpenCV
Un’ultima cosa molto importante รจ il collegamento simbolico di OpenCV 4 con la directory dei pacchetti del nostro ambiente virtuale. Bisogna entrare nella directory dei site-packages dellโambiente virtuale e linkare la libreria cv2.so. Ecco i comandi:
cd ~/.virtualenvs/cv/lib/python3.5/site-packages/ ln -s /usr/local/python/cv2/python-3.5/cv2.cpython-35m-arm-linux-gnueabihf.so cv2.so cd ~
Notate lโopzione โs di ln che sta per symbolic.
Se non si esegue questo passaggio, OpenCV 4 non riconoscerร i pacchetti dellโambiente virtuale di Python 3. A questo proposito controllare che nella directory ~/.virtualenvs/cv/lib/python3.5/site-packages sia presenti il link alla libreria cv2.so.
Virtual Environment in Python 3
Virtual Environment sta per ambiente virtuale. Si tratta di una pratica che permette di creare degli spazi indipendenti dal resto del sistema in cui รจ possibile testare e lavorare con Python e pip.
In altre parole, gli ambienti virtuali consentono di lavorare e sperimentare con piรน progetti contemporaneamente, nonostante questi utilizzino una versione diversa degli stessi moduli.
Inoltre, permettono di installare moduli con pip senza i privilegi di root, con tutti i vantaggi che questo comporta in termini di sicurezza.
In pratica, viene creata una cartella che conterrร i file necessari al funzionamento dellโambiente e una copia dei binary di Python. Dentro questa cartella potremo poi installare tutti i moduli con la versione che vogliamo in base al progetto su cui si sta lavorando.
Una volta creato un ambiente virtuale, basta attivarlo e iniziare a lavorare al suo interno.
Se non รจ giร stato fatto in precedenza, bisogna installare il pacchetto virtualenv con pip:
pip install virtualenv
Prima di tutto, si consiglia di creare una cartella di lavoro:
mkdir progetto cd progetto
Con il comando che segue si puรฒ creare lโambiente virtuale nella
cartella progetto, scegliendo un nome qualsiasi:
virtualenv env_name
Questo comando installerร tutti gli strumenti necessari allโinterno dellโambiente virtuale env_name.
Infine, ci si sposta nella cartella bin dellโambiente virtuale env_name
e lo si attiva con il comando activate:
cd env_name/bin source activate
Per disattivare lโambiente virtuale e tornare al prompt normale, basta digitare il comando deactivate.
![](https://futuranet.it/wp-content/uploads/2023/04/virtual-environment.jpg)
Schermata caratteristica del Virtual Environment
Verifica dellโinstallazione di OpenCV 4
Per vedere se OpenCV 4 รจ stato installato correttamente, rimanendo allโinterno dellโambiente virtuale cv, eseguire quanto segue dal terminale:
python >>> import cv2 >>> cv2.__version__ โ4.0.0โ >>> exit()
Come illustrato in Fig. 10, il primo comando apre lโinterprete Python 3 associato allโambiente cv.
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-10-1.jpg)
Fig. 10 Verifica dellโinstallazione di OpenCV 4
Il comando import cv2 importa la lib reria e il comando cv2.__version__ fa vedere la versione 4.0.0 della libreria. Con il comando exit() si esce dallโinterprete e si torna al terminale.
Ricordate che al riavvio del sistema bisogna riattivare ogni volta lโambiente virtuale (nel nostro caso โcvโ) e quindi iniziare a lavorare, con il comando workon cv:
source ~/. Profile workon cv
Per usare lโinterfaccia IDLE di Python 3 allโinterno dellโambiente virtuale รจ necessario digitare il seguente comando:
python -m idlelib.idle
Con lโinterfaccia IDLE aperta, si possono creare nuovi script o aprire quelli giร fatti in precedenza.
Se si tenta di aprire al di fuori dellโambiente virtuale uno script che importa la libreria cv2, apparirร il Traceback con lโavviso di errore:
ImportError: No module named โcv2โ.
Videosorveglianza con OpenCV 4 e Raspberry Pi
Abbiamo pensato a questo progetto come a una valida alternativa ai sistemi dโallarme basati su sensori PIR, a ultrasuoni, a contatto e cosรฌ via. Una volta rilevato un movimento, lo script fotografa lโintruso e manda la foto a un indirizzo di posta elettronica per identificare la persona.
Qualunque sia lo scopo, abbiamo creato lo script basato su OpenCV 4 per la cattura del movimento per lโinvio di email a un indirizzo di posta. Contemporaneamente, il movimento rilevato attiva una porta GPIO alla quale collegare eventualmente un relรจ e un sistema di allarme. Raspbian include le librerie per la gestione della posta e della porta GPIO, per cui non serve installare altro.
Di seguito commentiamo le parti salienti dello script (il codice completo potete scaricarlo dal nostro sito www.elettronicain.it). Le librerie importate allโinizio dello script servono solo alla gestione SMTP, ovvero allโinvio di e-mail tramite un server di posta noto. Per questo utilizzo, รจ necessario connettere Raspberry Pi alla rete WiFi o Ethernet.
from smtplib import SMTP_SSL as SMTP from email.mime.text import MIMEText from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from email import Encoders
Nella sezione che segue vanno cambiati i parametri per il server SMTP. Si consiglia di impiegare il server SMTP normalmente usato per lโinvio di posta dal computer di casa.
Le variabili sender e destination contengono gli indirizzi del mittente e del destinatario, ovvero lโindirizzo con il quale si mandano normalmente le email e lโindirizzo a cui si vuol inviare il messaggio.
Le variabili username e password sono il nome utente e la password usati per lโinvio al server SMTP. Il tipo di messaggio รจ di testo plain e la variabile content indica il contenuto del messaggio mentre la variabile subject riporta lโoggetto del messaggio. Lโistanza msg eredita i metodi della libreria MIMEMultipart.
SMTPserver = โsmtps.server.xxxโ sender = โ[email protected]โ destination = โ[email protected]โ username = โ[email protected]โ password = โmyPasswordโ text_subtype = โplainโ content=โMessaggioโ subject=โAllarmeโ msg = MIMEMultipart()
La funzione email_send() รจ designata allโinvio di unโemail con un allegato, che nel nostro caso รจ unโimmagine jpg dellโintruso o dellโoggetto che si รจ mosso nella stanza. Come vedremo piรน avanti, la funzione di invio e-mail รจ opzionale e puรฒ essere chiamata o meno nello script. Se lโinvio avviene correttamente, sul terminale verrร stampato โInvio eseguitoโ altrimenti apparirร โInvio fallitoโ.
def email_send(): try: msg[โSubjectโ]= subject msg[โFromโ] = sender msg[โToโ] = destination msg.attach(MIMEText(content, โplainโ)) msg.attach(part) conn = SMTP(SMTPserver) conn.set_debuglevel(False) conn.login(USERNAME, PASSWORD) try: conn.sendmail(sender, destination, msg.as_string()) print(โInvio eseguitoโ) finally: conn.quit() except Exception: print(โInvio fallitoโ)
Quelle che seguono sono le librerie che devono essere importate per la gestione della videocamera, della data, dellโorario, degli effetti video, dei file json, di cv2 (OpenCV 4) e della porta GPIO.
import cv2 import time import datetime import imutils import json import RPi.GPIO as GPIO from picamera.array import PiRGBArray from picamera import PiCamera
Le istruzioni seguenti impostano lโuscita GPIO26 (potete, da qui, sceglierne unโaltra):
GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(26,GPIO.OUT)
Lo script prevede lโimportazione di alcuni parametri attraverso un file di configurazione, che abbiamo chiamato appunto โconfigurazione.jsonโ. Grazie alla libreria json si puรฒ quindi fare il parsing dei valori assegnati ai parametri di configurazione e assegnarli alle variabili o alle funzioni. Lโistruzione che segue permette il caricamento del file json che viene spiegato nel prossimo paragrafo.
conf = json.load(open(โconfigurazione.jsonโ))
Il file configurazione.json
Di solito un file JSON (JavaScript Object Notation) viene usato nellโambiente di programmazione Javascript. Grazie alla sua versatilitร , viene usato spessissimo come file di configurazione in altri ambienti.
Si tratta di uno script che supporta il linguaggio Javascript e quindi accetta la sintassi tipica del linguaggio.
Aprendo il file โconfigurazione.jsonโ con un semplice editor di testo si possono vedere i parametri da assegnare a variabili e funzioni:
{ โuse_imgโ: true, โuse_emailโ: true, โvideo_previewโ: true, โmin_timeโ: 3.0, โmin_motionโ: 8, โthresholdโ: 5, โresolutionโ: [640, 480], โfpsโ: 25, โmin_areaโ: 5000 }
Come vedete, alcuni parametri sono posti a true o false e altri contengono valori numerici e array.
Leggendo questi parametri con la suddetta istruzione conf = json.load(open(โconfigurazione.jsonโ)), si possono impostare le funzionalitร dello script di videosorveglianza, senza dover toccare ogni volta il codice.
Per esempio, se non si vogliono salvare i file delle immagini catturate e usare la videosorveglianza solo per accendere il relรจ di allarme, basta scrivere nel file json la seguente istruzione:
โuse_imgโ: false
Allo stesso modo, se non si desidera lโinvio di email:
โuse_emailโ: false
Se non volete visualizzare la finestra di anteprima:
โvideo_previewโ: false
Gli altri parametri permettono di impostare:
โข min_time: valore predefinito 3 secondi; รจ il tempo minimo per rilevare il movimento;
โข min_motion: valore predefinito 8 frame; รจ il numero minimo di frame prima di attivare lโaccensione del LED, il salvataggio dei file e/o lโinvio dellโemail. Si puรฒ aumentare o diminuire il valore per rendere piรน o meno sensibile il rilevamento ;
โข threshold: valore predefinito 5; definisce la soglia di sensibilitร per il rilevamento del movimento. Si puรฒ aumentare o diminuire questo valore a seconda che si voglia rendere il contrasto piรน o meno sensibile;
โข resolution: (predefinito 640×480 pixel) รจ la risoluzione video, ovvero la dimensione del riquadro (frame) di preview; si consiglia di lasciare inalterata la risoluzione per evitare rallentamenti nel flusso video o nellโinvio delle e-mail;
โข fps: imposta i frame al secondo; si consiglia di lasciare il valore predefinito (25) per evitare rallentamenti nel flusso video;
โข min_area: predefinito 5000. ร il valore minimo dellโarea del riquadro verde che viene creata attorno al soggetto rilevato. Di solito non serve modificarla.
Proseguiamo con lโanalisi del codice: lโoggetto camera eredita i metodi della libreria picamera. I parametri della videocamera vengono impostati in base alla lettura dei parametri resolution e fps del file json. Notate lโuso del tipo tuple che in Python permette di creare una lista di valori separati da virgole:
camera = PiCamera() camera.resolution = tuple(conf[โresolutionโ]) camera.framerate = conf[โfpsโ] rawCapture = PiRGBArray(camera, size=tuple(conf[โresolutionโ]))
Vengono quindi definite alcune variabili che verranno utilizzate nello script per stabilire il tempo di inizio e di fine della cattura dei frame.
count = 0 avg = None motionCounter = 0 lastUploaded = datetime.datetime.now()
Allโavvio dello script, si potrร vedere sul terminale la scritta โAvvioโฆโ poi il sistema attende 2 secondi e inizia la cattura video. Si fa notare che nella finestra di preview viene sovraimposto nella parte alta il testo โStato attuale: Nessun movimentoโ e, in basso, la data e lโorario (Fig. 11).
A questo scopo, viene usata la libreria imutils per ridimensionare il frame e la libreria datetime per lโorario da Internet, per cui lโorario e la data dovrebbe essere precisi.
Con la libreria cv2 si imposta la maschera per rilevare un oggetto in movimento. Si fa notare che il parametro tresh legge il valore di soglia, ovvero il parametro threshold dal file json di configurazione. La variabile motionFlag viene posta a False.
print โAvvio...โ time.sleep(2)
Tutta la iterazione for serve a contare i frame e rilevare le differenze della maschera di grigio che viene sovraimposta allโimmagine catturata, come illustrato in Fig. 12. Il valore di treshold imposta la soglia di intervento per rilevare il movimento.
![](https://futuranet.it/wp-content/uploads/2023/04/Fig-12-1.jpg)
Fig. 12 Maschera di contrasto
for f in camera.capture_continuous(rawCapture, format=โbgrโ, use_video_port=True): frame = f.array timestamp = datetime.datetime.now() text = โNessun movimentoโ motionFlag = False frame = imutils.resize(frame, width=500) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (21, 21), 0) if avg is None: avg = gray.copy().astype(โfloatโ) rawCapture.truncate(0) continue cv2.accumulateWeighted(gray, avg, 0.5) frameDelta = cv2.absdiff(gray, cv2.convertScaleAbs(avg)) thresh = cv2.threshold(frameDelta, conf[โthresholdโ], 255, cv2.THRESH_BINARY)[1] thresh = cv2.dilate(thresh, None, iterations=2) (cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) โฆ โฆ
Rilevato un movimento, il soggetto viene evidenziato con riquadri verdi attorno ai bordi. Quando il valore di soglia viene superato, apparirร il testo โStato attuale: Movimento rilevatoโ e la variabile motionFlag viene posta a True.
text = โMovimento rilevatoโ motionFlag = True ts = timestamp.strftime(โ%A %d %B %Y %I:%M:%S%pโ)
A questo punto, se la variabile motionFlag รจ True, inizia il confronto fra il tempo corrente (currentTime) e il tempo impostato per il rilevamento (lastTime) impostato dal parametro min_time nel file json e inizia il conteggio dei movimenti rilevati con la variabile motionCounter.
if text == โMovimento rilevatoโ: if (currentTime - lastTime).seconds >= conf[โmin_timeโ]: motionCounter += 1
Se il numero dei movimenti rilevati supera quella impostato dal parametro min_motion nel file json, si puรฒ decidere se salvare il file jpg del soggetto. Questa opzione viene impostata dal parametro use_img del file json. Notate che il nome del file img = โfoto_โ + str(count) + โ.jpgโ segue una numerazione progressiva.
I nomi dei file vengono salvati localmente con lโistruzione cv2.imwrite(img, frame) come foto_1.jpg, foto_2.jpg e cosรฌ via.
if motionCounter >= conf[โmin_motionโ]: if conf[โuse_imgโ]: count += 1 img = โfoto_โ + str(count) + โ.jpgโ cv2.imwrite(img, frame)
Nel frattempo, il LED/relรฉ sul pin GPIO26 viene attivato o disattivato, mentre viene stampato โLED ONโ sul terminale, a seconda se viene rilevato o meno il movimento:
GPIO.output(26, GPIO.HIGH) print โLED ONโ.
oppure:
print (โLED OFFโ) GPIO.output(26,GPIO.LOW)
Se รจ stato impostato lโinvio dellโemail con il parametro use_email, viene creato lโoggetto part che imposta il formato MIME (Multipurpose Internet Mail Extensions) per comporre il messaggio di posta. Il messaggio viene automaticamente codificato in formato base64 e quindi spedito tramite la funzione email_send(),vista in precedenza.
Il messaggio di posta invierร in allegato il file โfoto_1.jpgโ e successivamente il file โfoto_2.jpgโ e cosรฌ via, in base alle volte che la videocamera rileva un nuovo movimento.
La Fig. 13 illustra un esempio di ricezione di unโe-mail di allarme.
if conf[โuse_emailโ]: part = MIMEBase(โapplicationโ, โoctet-streamโ) part.set_payload(open(t, โrbโ).read()) Encoders.encode_base64(part) part.add_header(โContent-Dispositionโ, โattachment; filename=โ+ img) email_send()
Conclusioni
Per ora รจ tutto. Per fare un poโ di esperienza potete provare a modificare il listato per aggiungere funzionalitร o modificare i parametri del file json per vedere cosa succede.
Se volete approfondire l’utilizzo di Open CV4 Futura Academy mette a disposizione un corso specifico.