Python per la Visione Artificiale: ricerca e didattica DIDAMATICA 2015 Angelo Monfroglio ITIS OMAR Via Beldì 19, 28068 Romentino (NO) [email protected] [email protected] Lavoro di ricerca (Full Paper) Tipologia: Esperienze e casi di studio Area tematica: Intelligenza artificiale, Interazione Persona-Calcolatore; Sistemi robotici nella didattica e per il lavoro Vengono descritte esperienze di ricerca e didattica sulla Visione Artificiale (Computer Vision) utilizzando le librerie Open Source SimpleCV (e OpenCV) in linguaggio Python. Si spiega l’importanza della scelta di Python come linguaggio di programmazione Open Source, multipiattaforma (PC, tablet e smartphone, schede a microcontrollore). Si esaminano due progetti: riconoscimento del contenuto di frutta o verdura in un sacchetto di plastica al supermercato; e riconoscimento di facce di studenti e docenti all’ingresso della scuola. 1. Introduzione La visione artificiale (Computer Vision) è la trasformazione di dati da una foto o video digitali in una rappresentazione o una decisione (ad esempio, muoversi in avanti, a destra, ecc.). La trasformazione è volta al raggiungimento di uno o più obiettivi. I dati in ingresso possono comprendere anche informazioni contestuali come la distanza del soggetto inquadrato, ottenute per mezzo di sensori, come localizzatori a LED, Laser, ultrasuoni, ecc. Un sistema elementare di visione (si veda([Mon, 2011]) è così costituito: 1.1 Cattura delle immagini con un sensore CCD o CMOS, come nelle foto e video camere digitali. Le immagini sono memorizzate in matrici a 2 dimensioni, con le coordinate X e Y, e i valori 0 e 1; oppure un valore per la scala di grigi; oppure un valore a colori (RGB). Un insieme di operatori chiamati filtri: ad esempio, la media sui valori dei pixel; oppure la soglia: 0 tutti i valori al di sotto della soglia, 1 sopra; cambiamento di contrasto e di luminosità 1.2 Algoritmo di rilevazione del contorno o perimetro (edge detection). E’ il primo algoritmo fondamentale e, in alcuni semplici casi, l’unico 1 necessario. Si estrae l’oggetto dal fondo, determinando lati, angoli, ecc. L’algoritmo è basato sul calcolo del gradiente (discreto) per ogni pixel lungo le direzioni vicine. Ad esempio: ordina i pixel nella matrice; per ogni pixel, analizza ognuno degli 8 pixel vicini; memorizza il valore più basso (scala dei grigi, o dei colori base RGB) e il più alto e il più basso; se (valore più alto – valore più basso) > soglia riscrive il valore del pixel come 1 altrimenti scrive 0. 1.3 Rilevazione di una forma e riconoscimento di una configurazione (Shape Detection e Pattern Recognition). Un caso comune è l’isolamento di una faccia e il riconoscimento di una identità. Si costruisce un data base di forme: si esegue il rilevamento dei contorni (passo precedente); si calcola il numero di lati contigui: un cambiamento repentino nella direzione significa linea diversa; se si identificano tre lati allora è un triangolo, se 4 un quadrato, se la linea è continua un cerchio, ecc 1.4 Centro di massa e rilevamento di blob (macchia di colore). L’algoritmo di Blob detection si usa per determinare se un gruppo di pixel sono tra loro correlati. Se c’è solo un blob, il centro di massa è facilmente determinabile. Se ce ne sono di più occorre etichettare ogni singolo blob. 1.5. Correlazione di immagini (Template Matching) e Riconoscimento facciale: si costruisce un data base di caratteristiche (features) e si calcola l’intensità di somiglianza. Un caso molto noto è il riconoscimento di una faccia. Si vedano [Sze, 2011],[Dem, 2012]. Riassumendo, un sistema per la Visione Artificiale prevede: 1. Filtraggio dei dati iniziali, sottraendo le informazioni non necessarie o che non è possibile elaborare per le limitazioni dell’hardware, e esaltando le informazioni utili riducendo i disturbi 2. Estrazione delle caratteristiche necessarie (Pattern Recognition). 2. Perché Python? Python è stato creato negli anni ’90 da Guido van Rossum. È un linguaggio moderno: multi paradigma, multipiattaforma e open source. È estremamente conciso ma, al tempo stesso molto leggibile. Un programma Python di solito è lungo un terzo di un programma Java o C++. Ha un ambiente di sviluppo facile da usare: editor e interprete integrati. E’ uno dei pochissimi linguaggi che gira su PC (Windows e Linux), tablet e smartphone Android, scheda Arduino, ecc. Può essere usato come semplice linguaggio per un corso introduttivo di Informatica, o per corsi avanzati sulla programmazione orientata agli oggetti. Ancora, è uno dei pochissimi linguaggi a infinita precisione, come il LISP, che tuttavia è poco diffuso, difficile e costoso. Infinita precisione significa che Python è in grado di allocare la quantità di memoria necessaria al calcolo in atto, 2 avendo come limite solo quello della memoria fisicamente disponibile. Si veda [Lut]. Va notato che è molto significativo per la didattica in Informatica far riflettere gli studenti sulla effettiva precisione di calcolo dei PC e delle calcolatrici. Se si opera con numeri interi molto grandi e si vogliono tutte le cifre e non un’approssimazione con una mantissa e un esponente, i linguaggi comuni o le calcolatrici non forniscono i risultati desiderati. Basta far calcolare un fattoriale con un numero non piccolo, anche solo 20 o 30,e si vede che le cifre esatte ottenute si fermano presto. L’infinita precisione di calcolo di Python si rivela indispensabile per alcune applicazioni di Matematica, come la compilazione di tabelle per calcoli esponenziali o logaritmici, ad esempio in campo statistico. Il seguente esempio di un programma Python per calcolare e visualizzare i numeri di Fibonacci, mostra che è impossibile scrivere un programma più corto e chiaro. a,b,f=1,0 n=input("Quanti numeri di Fibonacci? ") while f < n: m=a+b a=b b=m f=f+1 print m Python è un linguaggio di programmazione ad alto livello Open Source con un ambiente di programmazione semplice e completo, che sta guadagnando ampia popolarità: oggi è già tra i più utilizzati nel mondo. La sua filosofia è multi paradigma: object and functional oriented, structured. È inoltre di facile leggibilità e molto conciso. Dispone di un ambiente di sviluppo (IDE) che integra editor, compiler e debugger. Fra le molte applicazioni di Python, si segnalano le interfacce grafiche, la visione artificiale e applicazioni di matematica. Ad esempio, una ragazza ha presentato agli esami di Stato del 2014, un’applicazione di Python per la costruzione di tavole per la funzione di probabilità gaussiana con un numero di cifre di precisione mai finora realizzato. Esiste anche una versione per Android, per sviluppare app. Forniamo un esempio di programmazione per la fattorizzazione intera di un numero dispari non quadrato. 3 Un altro esempio: trovare i due fattori primi interi di un numero dispari con l’algoritmo di Fermat num = input ("Numero da fattorizzare ") x= int(math.sqrt(num)) x= x + 1 k=2*x+1 r = x ** 2 - num while math.floor(math.sqrt(r)) != math.sqrt(r): r=r+k k=k+2 else: x= (k - 1)/2 y = math.sqrt(r) m=x-y n=x+y print("Divisibile per ",int(n),int(m)) 2.1 Python per tutti Un esempio del classico saluto (Hello World) creando una nuova finestra. class LabelDemo(Frame): def __init__(self): Frame.__init__(self) self.master.title("Demo") self.grid() self._label = Label(self, text = "Hello self._label.grid() def main(): 4 World") LabelDemo().mainloop() main() Può essere eseguito anche su tablet o smartphone Android, con lievi modifiche: a. b. c. d. e. Entrare nel servizio SL4A (Scripting Layer for Android) Lanciare il Server Lanciare Python Eseguire import android Eseguire il programma qui riportato (senza la prima riga) Un esempio di uso di OpenCV SimpleCV con il sistema operativo Android: <manifest android:versionName="1.0" android:versionCode="1" package="org.opencv.samples.tutorial2" xmlns:android="http://schemas.android.com/apk/res/android"><supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:resizeable="true"/><application android:icon="@drawable/icon" android:label="@string/app_name"><activity android:label="@string/app_name" android:configChanges="keyboardHidden|orientation" android:screenOrientation="landscape" android:name="Sample2NativeCamera"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application><uses-sdk android:minSdkVersion="8"/><uses-permission android:name="android.permission.CAMERA"/><uses-feature android:name="android.hardware.camera"/><uses-feature android:name="android.hardware.camera.autofocus"/></manifest> from tkinter import * 3. Python per la visione artificiale: Simple CV Nel 1999 la ricerca Intel ha reso disponibile OpenCV, una libreria di funzioni in linguaggio C e C++ per la Computer Vision. È molto ricca di algoritmi già pronti per l’uso, dalle funzioni più semplici per le elaborazioni e il filtraggio dei dati iniziali da immagini registrate e in tempo reale da WevCam, fino alle funzioni avanzate di estrazione di caratteristiche. Tuttavia, non è di semplice utilizzo in una Scuola Media Superiore. Fortunatamente, è da poco disponibile SimpleCV, una libreria in linguaggio Python, che si appoggia allo strato sottostante di OpenCV, e che, come suggerisce il nome, è di facile utilizzo. Il pacchetto Open Source di installazione installa automaticamente anche OpenCV, oltre ai pacchetti di supporto in Python NumPy (una libreria potente di algoritmi di elaborazione numerica che sfrutta le caratteristiche di Python), SciPy, e Python Setup Tools. Ecco un esempio di programma che visualizza WebCam di un PC portatile: 5 in tempo reale un’immagine dalla from SimpleCV import Camera,Display,Image cam = Camera() display = Display() img = cam.getImage() img.save(display) Effetto prodotto dall’esecuzione del programma che crea un istogramma del colore per la faccia su un PC portatile con WebCam incorporata 4. Il progetto Il progetto educativo coinvolge gli indirizzi di Elettronica (Robotica) e Informatica(con Telecomunicazioni). È previsto l’insegnamento del linguaggio di programmazione Python in terza e quarta(programmazione ad oggetti). In quinta viene sviluppata l’applicazione di Visione Artificiale (Computer Vision). Sono stati proposti e sperimentati, in due quinte, il progetto di riconoscimento della frutta o verdura in un sacchetto di plastica presso un supermercato, e il riconoscimento delle facce di studenti e docenti (e personale di segreteria), al cancello di ingresso della scuola. Per entrambi i progetti si è sviluppata la realizzazione su PC desktop, PC portatile e (parzialmente) su tablet (o smartphone), e su microcontrollore Beaglebone (compatibile con Arduino). 4.1 Un’applicazione: sacchetto della frutta e verdura in un supermercato 6 Una situazione comune nei supermercati è quella di inserire frutta o verdura in sacchetti di plastica trasparente, selezionare il numero corrispondente al prodotto scelto, e battere il numero sulla pesa ottenendo lo scontrino con il prezzo da appiccicare sul sacchetto. Per errore, o più spesso per intento truffaldino, è comune il caso in cui il cliente sceglie un numero corrispondente a un prodotto di minore prezzo, danneggiando ovviamente il supermercato. Infatti, alla cassa, non è quasi mai possibile, anche per la fretta, verificare la corrispondenza dell’etichetta con il prodotto effettivamente presente nel sacchetto. Si è pensato allora di installare accanto alla spesa un sistema di Visione Artificiale in grado di riconoscere la merce nel sacchetto e bloccare l’erogazione dell’etichetta se il numero impostato non corrisponde al prodotto scelto. Abbiamo sperimentato la necessità di operare nello spazio di colore additivo HSV (conosciuto anche come HSB Hue = tinta, Saturation = saturazione, Brightness = intensità) invece dello spazio RGB usato comunemente, perché i risultati di riconoscimento sono più accurati e sicuri. 4.2 Un’altra applicazione: riconoscimento della faccia di uno studente o professore Il caso esaminato è quello del cancello di ingresso per studenti e docenti (e personale di segreteria o bidelli) della scuola. Alcuni istituti hanno installato un sistema di video sorveglianza che si dimostra tuttavia alquanto scomodo: il portinaio deve ogni volta controllare a distanza la persona o le persone che vogliono entrare, e aprire il cancello. Si è pensato dunque di ricorrere ad un sistema di Visione Artificiale che riconosce la faccia o le facce di chi sta per entrare. Bisogna subito distinguere il Riconoscimento di una Faccia (Face Recognition) dalla Rivelazione della presenza di un Faccia (Face Detection). Quest’ultima, ormai presente in molte fotocamere e videocamere digitali, si limita a rilevare la presenza di una faccia, ma non è in grado di riconoscere la persona 7 corrispondente. La Face Recognition è un compito molto arduo. Per fortuna, SimpleCV mette a disposizioni alcune funzioni molto utili: riconoscimento di profili, nasi, occhi, bocche e orecchie.Questi caratteri singoli sono combinati per il Template Matching, il confronto con immagini registrate per arrivare ad un certo grado di probabilità di riconoscimento. Sono queste le funzioni che abbiamo utilizzato. Caratteristiche per il riconoscimento di un volto e il relativo programma import numpy as np import cv2 import cv2.cv as cv from video import create_capture from common import clock, draw_str help_message = ''' USAGE: facedetect.py [--cascade <cascade_fn>] [--nested-cascade <cascade_fn>] [<video_source>] ''' def detect(img, cascade): rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30), flags = cv.CV_HAAR_SCALE_IMAGE) if len(rects) == 0: return [] rects[:,2:] += rects[:,:2] return rects def draw_rects(img, rects, color): for x1, y1, x2, y2 in rects: cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) if __name__ == '__main__': import sys, getopt 8 print help_message args, video_src = getopt.getopt(sys.argv[1:], '', ['cascade=', 'nested-cascade=']) try: video_src = video_src[0] except: video_src = 'synth:bg=../cpp/lena.jpg:noise=0.05' args = dict(args) cascade_fn = args.get('--cascade', "../../data/haarcascades/haarcascade_frontalface_alt.xml") nested_fn = args.get('--nested-cascade', "../../data/haarcascades/haarcascade_eye.xml") cascade = cv2.CascadeClassifier(cascade_fn) nested = cv2.CascadeClassifier(nested_fn) cam = create_capture(video_src) while True: ret, img = cam.read() gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.equalizeHist(gray) t = clock() rects = detect(gray, cascade) vis = img.copy() draw_rects(vis, rects, (0, 255, 0)) for x1, y1, x2, y2 in rects: roi = gray[y1:y2, x1:x2] vis_roi = vis[y1:y2, x1:x2] subrects = detect(roi.copy(), nested) draw_rects(vis_roi, subrects, (255, 0, 0)) dt = clock() - t draw_str(vis, (20, 20), 'time: %.1f ms' % (dt*1000)) cv2.imshow('facedetect', vis) if cv2.waitKey(5) == 27: break Uso di filtri 9 5. Valore didattico e educativo Il primo progetto descritto è a buon punto. Il secondo richiede più tempo, anche per il lungo lavoro di registrazione dei dati morfologici e biometrici delle persone da identificare. Oggi PC, PC portatili, smartphone e tablet sono di uso comune presso gli studenti che li usano, tra l’altro, per navigare in internet e scaricare applicazioni. Si è pensato di sviluppare progetti di Visione Artificiale da parte degli studenti che diventano così protagonisti attivi sia dell’Intelligenza Artificiale, sia del Mobile Computing. Si può colmare la distanza fra l’informatica spicciola usata dagli studenti nel gestire gli smart phone, e quella da studiare a scuola. La robotica è poi una disciplina sufficientemente complessa per educare gli studenti a gestire la complessità del mondo moderno. Il progetto di Computer Vision si è dimostrato molto coinvolgente per i partecipanti: studenti e docenti. I progetti qui descritti si inseriscono in un’esperienza di 25 anni relativa alla Robotica ed Intelligenza Artificiale presso l’ITIS Omar di Novara. La collaborazione con il Politecnico di Torino e quello di Milano, anche per gli allievi che sostengono il tirocinio presso l’Omar, la collaborazione fra due indirizzi della scuola, l’uso di linguaggi avanzati di programmazione, rappresentano nelle nostre intenzioni la migliore realizzazione dello spirito e delle finalità di Didamatica. 6. Bibliografia [Lutz] M. Lutz, Learning Python, O’Reilly, 2009 [Mon] R. Szeliski, Computer Vision, Algorithms and Applications, Springer, 2011 A.Monfroglio, Visione Artificiale in un IT IS: ricerca e didattica, Didamatica, Torino, 2011 [Dem] K. Demaged, A. Oliver, N. Oostendorp, K. Scott, Practical Computer Vision with Simple CV, O’Reilly, 2012 L’autore Angelo Monfroglio si è laureato in Ingegneria Elettronica al Politecnico di Milano, ed è abilitato in Elettronica, Informatica e Matematica. Ha tenuto relazioni a Didamatica Milano , Torino e Pisa. Ha pubblicato libri (e ebook) e articoli su ricerca e didattica informatica, in riviste accademiche specializzate in Italiano e Inglese. 10