Introduzione
In questo articolo cominceremo a fare una delle operazioni basilari con la libreria OpenCV. Vedremo come disegnare delle figure geometriche e aggiungere del testo sopra un’immagine preesistente.
Per poter seguire gli esempi presenti in questo articolo è necessario avere installata la libreria opencv per Python. Per chi non l’avesse ancora fatto consiglio vivamente di seguire le istruzioni riportate nel seguente articolo:
- OpenCV 3.0 & Python – Installazione su Raspberry (Raspbian)
- OpenCV 3.0 & Python – Caricare, visualizzare e salvare le immagini su Raspberry
Gli esempi seguenti sono stati tutti eseguiti su Raspberry Pi 3 Model B
Disegnare su una immagine con OpenCV
Una delle operazioni base di OpenCV è la possibilità di disegnare sopra delle immagini. La possibilità di aggiungere linee, cerchi e figure geometriche sopra una immagine è un’operazione che si rivelerà molto utile in seguito.
Spesso lavorando con l’analisi delle immagini, si vuole evidenziare una porzione di immagine, per esempio aggiungendo un rettangolo che delimita quella porzione, o per esempio una freccia che lo indichi. Altri esempi per esempio potrebbero essere l’aggiunta di una griglia, oppure l’aggiunta di un contorno che delimiti una figura, ecc….
Durante questo articolo vedremo che queste operazioni si possono effettuare tramite semplici funzioni, ognuna specializzata per una data figura geometrica base in cui verranno specificate le coordinate geometriche che le definiscono. Queste figure geometriche base sono spesso chiamate primitive, e sono figure basilari come punti, linee, cerchi, rettangoli) che permettono la costruzione di figure geometriche più complesse.
Chi in genere ha lavorato già con altri linguaggi di programmazione per disegnare, troverà questa serie di comandi molto facile ed intuitiva, per chi non avesse familiarità con questa tipologia di comandi, non si deve preoccupare dato che negli esempi seguenti, ogni comando verrà spiegato in dettaglio e passo per passo.
Prima di cominciare
Apriamo una sessione di terminale e facciamo partire l’ambiente virtuale su cui è installato openCV 3.0 per Python.
$ source ~/.profile $ workon cv (cv) $
Per comodità, in questo esempio utilizzeremo uno sfondo nero su cui costruiremo le figure geometriche. Creiamo un file draw01.py con un editor di testo.
$ nano draw01.py
ed inseriamo il codice seguente
import numpy as np import cv2 as cv img = np.zeros((512,512,3), np.uint8) cv.imshow('Draw01',img) cv.waitKey(0)
Questo sarà il codice di partenza degli esempi a seguire. Se eseguite il codice otterrete una finestra con sfondo completamente nero.
$ python draw01.py
Disegnare una linea
Per prima cosa vediamo come si può disegnare una linea. La funzione per disegnare una liena su schermo è cv2.line. Questa funzione accetta 5 argomenti:
- l’oggetto immagine su cui disegnare
- le coordinate del punto di inizio (x,y)
- le coordinate del punto di fine (x,y)
- il colore del tratto in BGR (non RGB attenti)
- lo spessore del tratto di linea (in pixel)
Per esempio aggiungiamo una linea diagonale rossa con uno spessore di 4 pixel. E’ sufficiente aggiungere la riga
img = cv.line(img, (100,100), (300,300), (0,0,255),4)
al codice precedente, immediatamente dopo la definizione di img.
import numpy as np import cv2 as cv img = np.zeros((512,512,3), np.uint8) #draw a red line img = cv.line(img, (100,100), (300,300), (0,0,255),4) cv.imshow('Draw01',img) cv.waitKey(0)
Lanciando il programma vedrete la riga rossa.
Disegnare un Rettangolo
Per disegnare un rettangolo, la funzione è molto simile e si chiama cv2.rectangle. Anche questa funzione accetta cinque parametri in ingresso:
- l’oggetto immagine su cui disegnare
- le coordinate del vertice in alto a sinistra (x,y)
- le coordinate del vertice in basso a destra (x,y)
- il colore del tratto in BGR (non RGB attenti)
- lo spessore del tratto di linea (in pixel)
Quindi aggiungiamo la seguente riga al codice precedente.
img = cv.rectangle(img, (250,30), (450,200), (0,255,0), 5)
Otterremo un rettangolo verde in alto a destra.
Disegnare cerchi ed ellissi
In maniera davvero molto semplice e simile alle precedenti è possibile disegnare ellissi e cerchi tramite le funzioni cv2.circle e cv2.ellipse.
La funzione circle() richiede 5 argomenti:
- l’oggetto immagine su cui disegnare
- le coordinate del centro (x,y)
- il raggio del cerchio
- il colore del tratto in BGR (non RGB attenti)
- lo spessore del tratto di linea (in pixel)
Ecco un esempio di una circonferenza blu di raggio 20 e con il tratto di spessore di 3 pixel.
img = cv.circle(img, (100, 400), 20, (255,0,0), 3)
Mentre la funzione ellipse() è un po’ più complessa rispetto alla precedenti e richiede 8 argomenti:
- l’oggetto immagine su cui disegnare
- le coordinate del centro (x,y)
- la lunghezza degli assi minore e maggiore (h,w)
- l’angolo di rotazione dell’ellisse (calcolato in senso antiorario)
- l’angolo di partenza (calcolato in senso orario)
- l’angolo finale (calcolato in senso orario)
- il colore del tratto in BGR (non RGB attenti)img,
- lo spessore del tratto di linea (in pixel)
Ecco un esempio di arco di ellisse di color bianco ruotato di 45 gradi e di color bianco.
img = cv.ellipse(img, (300, 450), (100, 50), 45, 130, 270, (255,255,255), 1)
Inserendo le due righe nel codice draw01.py otterrete il risultato seguente:
Disegnare un poligono
Infine tra le primitive, la forma più complessa è il poligono. Dato che un poligono può avere n vertici (che può assumere qualsiasi valore) e per essere rappresentato richiederebbe n argomenti in relazione ad n punti con coordinate (x,y) da definire, si utilizzerà un array. In questo modo è tutto molto più semplice.
La funzione utilizzata è cv2.polylines e accetta generalmente
- l’oggetto immagine su cui disegnare
- l’array di coordinate
- True se è una linea chiusa
- colore del tratto
- spessore del tratto
Per esempio disegnamo un pentagono giallo:
vrx = np.array(([20,80],[60,50],[100.80],[80,120],[40,120]], np.int32) vrx = vrx.reshape((-1,1,2)) img = cv.polylines(img, [vrx], True, (0,255,255),3)
Possiamo inserire le righe precedenti nel codice sostituendo i comandi precedenti. Otterremo la figura seguente:
Disegnare figure geometriche sopra immagini
Adesso che abbiamo visto come sia facile disegnare le figure geometriche e quali funzioni e parametri sono necessarie per definirle, il prossimo passo sarà quelli di aggiungerle direttamente sopra un’immagine. Le immagini possono essere di qualunque formato. Per questo esempio utilizzeremo la classica immagine logos.jpg. (scaricatela direttamente dall’immagine sottostante).
Quindi carichiamo l’immagine con OpenCV (se vuoi approfondire questo argomento ti raccomando di leggere la prima parte di questa serie di articoli). Apri un editor di testo e crea il file draw02.py.
import numpy as np import cv2 as cv img = cv.imread('logos.jpg') img = cv.rectangle(img, (250,70), (330,150), (0,255,0), 4) cv.imshow('Draw01',img) cv.waitKey(0)
Come puoi vedere il codice disegnerà un rettangolo verde in corrispondenza di una delle icone presenti in figura.
Scrivere testo su immagini
Ultima parte di questo articolo è sulla scrittura di testo sulle immagini. Infatti molte volte non solo le figure geometriche sono utili per aggiungere indicazioni su immagini preesistenti, ma anche dei testi possono aggiungere molte informazioni.
I principi alla base sono gli stessi. Prima però di aggiungere il testo vero e proprio vediamo i FONT che OpenCV ci mette a disposizione. Queste font sono descritte attraverso una enumerazione.
FONT_HERSHEY_SIMPLEX = 0,
FONT_HERSHEY_PLAIN = 1,
FONT_HERSHEY_DUPLEX = 2,
FONT_HERSHEY_COMPLEX = 3,
FONT_HERSHEY_TRIPLEX = 4,
FONT_HERSHEY_COMPLEX_SMALL = 5,
FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
FONT_HERSHEY_SCRIPT_COMPLEX = 7,
Ne prendiamo una di queste, per esempio la prima e aggiungiamo una riga al codice:
font = cv.FONT_HERSHEY_SIMPLEX
Poi per disegnare del testo con OpenCV esiste la funzione cv2.putText che accetta una serie di argomenti:
- l’immagine su cui disegnare
- il testo da scrivere
- le coordinate del punto di partenza del testo
- la font da utilizzare
- la dimensione del carattere
- il colore del testo
- lo spessore del tratto del testo
- il tipo di linea utilizzato
Quindi se vogliamo aggiungere un testo alla nostra immagine precedente logos.jpg, scriviamo la riga seguente, aggiungendola al codice.
cv.putText(img, 'This one!", (230, 50), font, 0.8, (0, 255, 0), 2, cv.LINE_AA)
Eseguiamo il codice e otterremo:
Conclusioni
Con questo semplice articolo abbiamo visto come aggiungere delle figure e del testo sulle immagini utilizzando la libreria OpenCV. Negli articoli successivi questa operazione basilare sarà molto importante ed essenziale, e ci aiuterà ad evidenziare i nostri risultati durante l’analisi delle immagini.