Nuova sezione libri disponibile!

Sviluppare un rilevatore di fiamma con la visione artificiale

Gabriele Ermacora

lettura in 5 minuti

In occasione dell'alternanza scuola-lavoro all'ITIS Pininfarina di Torino, dove lo scopo è inventare applicazioni robotiche in ambito agricolo, stavo pensando di inventare qualcosa per risolvere il problema del rilevamento incendi. Allora mi è venuto in mente di implementare una semplice applicazione di visione artificiale che rilevi le sfumature di rosso e ci comunichi quando il robot "vede" una fiamma.

Il problema ovviamente può essere affrontato in modo molto più complesso e con molti altri sensori (temperatura, gas, ecc), però per iniziare in modo low-cost e con poche righe di codice mi sembra un'applicazione carina!

1. Ingredienti

Ci serve:

  • una Raspicam (io uso la V2)
  • un Raspberry Pi con l'immagine HBrain sull'SD

2. Collegare la raspicam al Raspberry

Seguite il tutorial scritto in precedenza che trovate qui. Connessione Camera Una volta che è tutto funzionante possiamo procedere con il codice. Andiamo nella sezione della piattaforma cloud adibita a creare nuovi "sketches" e iniziamo a scrivere un nodo!

2.1 Rilevare il colore rosso - Il codice

Il codice completo è qui sotto, copialo nello sketch, salva e premi "run".

import dotbot_ros
import cv2
import sys
import rospy
import numpy as np
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

class Node(dotbot_ros.DotbotNode):
    node_name = 'fire_detection'

    def setup(self):
        self.image_sub = dotbot_ros.Subscriber("/camera/image",Image,self.on_image)
        self.image_pub = dotbot_ros.Publisher("image_back", Image)
        self.img = None
        self.bridge = CvBridge()
        print "ci sono e sono vivo!"
        sys.stdout.flush()

    def on_image(self,data):

        img = self.bridge.imgmsg_to_cv2(data, "bgr8")

        # significa in RGB ROSSO
        lower = np.array([17, 15, 100])
        upper = np.array([50, 56, 200])

        tol = 0
        mask = cv2.inRange(img, lower, upper)
        output = cv2.bitwise_and(img, img, mask = mask)
        gray = cv2.cvtColor(output,cv2.COLOR_BGR2GRAY)

        if (gray>tol).any():
            print "Allarme Incendio !!!"
        else:
            print "---"

        sys.stdout.flush()
        self.image_pub.publish(self.bridge.cv2_to_imgmsg(gray, "mono8"))

Se è tutto ok, vedrai nella sezione "console" il nodo in esecuzione e facendo echo sui due topic "/camera/image" e "< nome-del-tuo-robot >/image_back" vedrai da una parte lo streaming dalla telecamera e dall'altra l'immagine solo se ha "qualcosa di rosso". NB: L'immagine la vedrete con i colori invertiti probabilmente per un problema sul Raspberry e l'immagine salta continuamnente da RGB a BGR e viceversa. Per questo ogni tanto il colore blu appare come rosso ;)

3. Analizziamo meglio il codice

A parte le prime righe dove si aggiungono i componenti Python necessari al programma, si instanzia una classe e si dichiara il nome del nodo come "fire_detection", vediamo in dettaglio il resto del codice.

Nella funzione setup, dichiariamo un subscriber che si sottoscrive al topic /camera/image, con un tipo di messaggio Image e associa una funzione di callback di nome on_image. Questa funzione verrà richiamata ogni volta che nel topic viene pubblicato un messaggio di tipo Image. Nella riga sotto dichiariamo un Publisher che ha l'obiettivo di pubblicare l'immagina processata. In questo modo così possiamo vedere l'effetto del filtro colore che stiamo per applicare. Alla fine della funzione mettiamo un print "ci sono e sono vivo!" per comunicare in console che il programma è in esecuzione correttamente.


def setup(self):
    self.image_sub = dotbot_ros.Subscriber("/camera/image",Image,self.on_image)
    self.image_pub = dotbot_ros.Publisher("image_back", Image)
    self.img = None
    self.bridge = CvBridge()
    print "ci sono e sono vivo!"
    sys.stdout.flush()

Vediamo ora la funzione on_image dove accade il vero e proprio filtraggio.

def on_image(self,data):

    #convertiamo l'immagine da opencv nel formato idoneo a ROS
    img = self.bridge.imgmsg_to_cv2(data, "bgr8")

    # significa in RGB ROSSO
    lower = np.array([17, 15, 100])
    upper = np.array([50, 56, 200])

Con lower e upper definiamo le soglie di colore rosso minime e massime, Ovvero in BGR (Blue Green Red) il colore che andremo a filtrare da ogni frame della telecamera. Se sei curioso di sapere esattamente che colore è, qui c'è un calcolatore RGB. NB: i colori nel codice Python sono in BGR quindi significa ad esempio per lower Blue = 17, Green = 15, Red = 100.

    # tolleranza
    tol = 0
    # maschera per sogliare il colore rosso
    mask = cv2.inRange(img, lower, upper)
    # immagine output dove rimane solo il rosso e tutto il resto nero
    output = cv2.bitwise_and(img, img, mask = mask)
    #converto questa in bianco e nero
    gray = cv2.cvtColor(output,cv2.COLOR_BGR2GRAY)

    # se c'è anche solo un pixel rosso mando un allarme!
    if (gray>tol).any():
        print "Allarme Incendio !!!"
    else:
        print "---"

    sys.stdout.flush()

    # pubblico l'immagine processata su image_back
    self.image_pub.publish(self.bridge.cv2_to_imgmsg(gray, "mono8"))

Qui facciamo qualche operazione più complicata. Bisogna innanzitutto dire che un'immagine è una matrice di numeri. Quindi in questo caso andiamo a definire una maschera mask, poi filtriamo nei range di colore definito e salviamo il risultato in un'altra immagine di nome output. Dopo convertiamo questa in bianco e nero e salviamo in un'altra immagine ancora di nome gray. Facciamo questa operazione perchè se la telecamera non vede niente di rosso (e nessun colore nel range definito prima) il nostro risultato sarà completamente nero, potete verificarlo in ROS console osservando il topic /image*back, il che significa che tutti i numeri della matrice sono 0 o praticamente 0. Quindi per capire in automatico se la telecamera "vede" una zona rossa basterà con *(gray>tol).any()_ andare a vedere se uno tra i tanti pixel dell'immagine NON è nero. Ovvero si traduce nell'osservare tutti gli elementi della matrice e vedere se ce n'è uno che è maggiore di una piccola tolleranza (in questo caso tol = 0 quindi il sistema sarà parecchio sensibile). Infine con _self.image_pub.publish()_ pubblichiamo il risultato sultopic /image_back.

4. Esercizi

Collegate un LED al Raspberry o fate inviare tramite un bot Telegram un messaggio di allarme sul vostro cellulare.

Migliorate l'applicazione con tecniche più fini di riconoscimento immagini, non solo un pixel ma una regione minima di spazio che possa essere effettivamente una fiamma!

Ciao ciao! :robot:

Ti è piaciuto questo post?

Registrati alla newsletter per rimanere sempre aggiornato!

Ci tengo alla tua privacy. Leggi di più sulla mia Privacy Policy.

Ti potrebbe anche interessare

HB Cloud Tutorial #1 - Uso dei Led
Iniziamo ad utilizzare la piattaforma di Cloud Robotics
HB Cloud Tutorial #2 - Uso dei Bottoni
Rieccomi con il secondo tutorial legato all'uso dei bottoni per il robot **DotBot-ROS**. In questo tutorial, vedremo come configurare ed utilizzare in Python un bottone attaccato ad un pin GPIO del Raspberry Pi 3.
HB Cloud Tutorial #3 - I Motori
I Motori sono una delle parti essenziali dei robot. In questo tutorial, vederemo come è possibile in modo semplice ed intuitivo implementare un programma in Python che controlla i motori in base a comandi inviati via Wifi al Robot.
HB Cloud Tutorial - Speech Bot: come far parlare il vostro robot
Le basi per costruire un "dialogo" con il vostro robot sfruttando le funzionalità di sintesi e riconoscimento vocale.
Non avete un robot? C'è il robot in cloud accessibile da remoto tramite il vostro PC o da cellulare
Non avete un robot? C'è il robot in cloud accessibile da remoto tramite il vostro PC o cellulare
Avete problemi hardware? C'è il robot in cloud accessibile da remoto tramite il vostro PC o cellulare
Avete problemi hardware? C'è il robot in cloud accessibile da remoto tramite il vostro PC o cellulare
Cosa si può fare con la nostra piattaforma di Cloud Robotics
Ecco alcune cosa che è possibile fare con la nostra piattaforma di Cloud Robotics
Tutorial - Usiamo la piattaforma di Cloud Robotics per sviluppare un semplice assistente personale Robotico
Usiamo la piattaforma di Cloud Robotics per sviluppare un semplice assistente personale Robotico
Utilizzare la RaspiCam in streaming con la piattaforma Cloud
Breve tutorial che spiega come abilitare la RaspiCam su ROS e la piattaforma di Cloud Robotics
Inviare Goals alla Navigation Stack - versione nodo ROS Python
Inviare un goal all ROS navigation stack utilizzando un nodo Python
Controllare siBOT dalla piattaforma HBR
Come controllare il manipolatore siBOT utilizzando la piattaforma HBR
Scriviamo un Blog in Python e Flask
Tutorial su come implementare, a partire da zero, un blog personale utilizzando Python e Flask! Prima parte!
Un laboratorio di Fisica con Arduino e Python
Primi esperimenti con Arduino e Python per realizzare un semplice laboratorio di fisica sfruttando la potenza di Python e la versatilità di Arduino
Canopy: una Pythonica alternativa a Matlab
Presento questo interessante tool python che può essere considerato una buona alternativa a Matlab per l'analisi dei dati!
Spyder, un'altra alternativa in Python a Matlab
Una velocissima prova del tool interattivo Spyder per l'analisi scientifica in Python
Simuliamo il moto parabolico in Python e Spyder
Un piccolo tutorial per iniziare ad utilizzare Spyder con Python
Python + Arduino = Nanpy
Programmare Arduino in Python con Nanpy
Utilizzo di Nanpy con il sensore di temperatura/umidità della famiglia DHT
Come utilizzare Nanpy col sensore DHT di temperatura e Umidità
Accendere led con Arduino e Telegram
Un bot telegram in grado di controllare Arduino realizzato da 3 ragazzi del Liceo Stampacchia
Implementiamo un bot Telegram con Python
Una semplice guida per iniziare a muovere i primi passi nello sviluppo di chatbot Telegram con Python
Pillole di Python: pyscreenshot
Una semplice tutorial che mostra il funzionamento della libreria pyscreenshot
Python Decorators
Introduzione ai decoratori in Python
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 1
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Implementiamo un bot Telegram con Python - I Comandi
Vediamo come gestire i comandi del nostro bot in Telegram
4 (+1) Libri su Python (in Inglese) da cui imparare
Una lista di libri su Python (in Inglese) da cui ho imparato a programmare
Virtualenv: gestiamo meglio le dipendenze in Python
A cosa servono e come si utilizzano i virtualenv Python
Leggere i codici a barre con OpenCV e zbar in Python
Come usare Python per leggere i codici a barre degli alimenti e ricavarne alcune informazioni utili
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 2
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Sviluppiamo un bot Telegram che legge i codici a barre degli alimenti
Implementiamo un bot Telegram in grado di leggere ed analizzare le immagini per la lettura ed interpretazione dei codici a barre
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 3
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Divertiamoci sviluppando UI da terminale con ASCIIMATICS
Le UI da terminale fanno molto anni '80, però sono sempre diventerti da implementare. Oggi vi voglio introdurre ad una semplice libreria per creare questo tipo di applicazione.
Sviluppiamo un Robot con tecnologie Open Source
Inizio una serie di videoguide, in cui voglio introdurvi al mondo della robotica di servizio in modo pratico, facendo vedere come è possibilile, sfruttando tecnologie completamente Open Source, quali Arduino, Raspberry Pi, ROS e Docker, costruire un piccolo robot di Servizio.
Parliamo come GMaps: come creare file audio con gtts (Google Text to Speech) in Python
gtts è una libreria in Python per sfruttare le API di Google Text to Speech per generare file audio dal testo
Robot Open Source - Introduzione a Docker
È disponibile il video "Introduzione a Docker".
I chatbot possono Parlare? Sviluppiamo un bot telegram che manda messaggi vocali
Usiamo le API di sintesi vocale di google per creare un bot in grado di mandare messaggi vocali
Robot Open Source - Docker e Raspberry
È disponibile il video "Docker e Raspberry".