A.A. 2010/2011 Elaborazione dell Immagine M Introduzione a OpenCV Federico Tombari Samuele Salti
La libreria Open CV Open Computer Vision Library: collezione di algoritmi open source per la computer vision e l image processing Sviluppato originariamente da Intel, attualmente un team di sviluppatori è finanziato da Willow Garage (http://opencv.willowgarage.com ) Utilizza le IPP - Integrated Performance Primitives - di Intel (prestazioni migliori su processori Intel) Versione attuale: 2.2 Scaricabile gratuitamente da: http://sourceforge.net/projects/opencvlibrary Disponibile per ambiente Windows e Unix Nel nostro corso: S.O. : Windows-based Ambiente di sviluppo: Visual.NET 2005 OpenCV: versione per windows!
Materiale delle esercitazioni Scaricabile al sito del corso: didattica.arces.unibo.it Prof. Luigi Di Stefano Elaborazione dell Immagine LS Materiale didatttico Materiale relativo alle esercitazioni di laboratorio Software ElabImage, Libreria OpenCV e Documentazione (file zip) Progetto di esempio contenuto nella sotto-directory Elabimage
4 librerie principali: Struttura di OpenCV pre 2.2 CV: kernel delle funzioni di IP/CV Image processing Motion analysis Pattern recognition 3D reconstruction CxCore: funzioni a supporto Strutture dati principali Accesso alle strutture dati (creazione, inserimento/modifica valori, copia,..) Operazioni su matrici (aritmetiche, logiche, trasformazioni, permutazioni,..) Disegno (punti, linee, curve, figure,..) HighGui: semplici operazioni di I/O: Creazione/distruzione finestre per mostrare immagini Apertura/salvataggio immagini Gestione flusso video (da file e da cam) CvCam
Struttura di OpenCV 2.2 Molte più librerie, permette di linkare solo con feature richieste core: definisce tipi base, come punti, vettori, matrici mono e multi-canale(immagini), algebra lineare, DFT, XML e YAML I/O imgproc: filtraggio, morfologia, resize, remap, conversione spazi di colore, istogrammi, etc.. highgui: Creazione/distruzione finestre per mostrare immagini, riproduzione di video, calib3d: camera calibration, matching stereo, features2d 2D feature detectors and descriptors (SIFT, SURF, FAST, etc., including the new feature detectors-descriptor-matcher framework) flann: wrapper della Fast Library for Approximate Nearest Neighbors (FLANN 1.5) per la ricerca dei Nearest Neighbors in spazi ad alta dimensionalità ml: algoritmi di machine learning (SVM, Decision Trees, Boosting etc.) objdetect: object detection in singole immagini(haar & LBP face detectors, HOG people detector etc.) video: algoritmi realtivi a sequenze video(tracking, optical flow, background subtraction, ) gpu: acceleration of some OpenCV functionality using CUDA (stereo, HOG, linear algebra) contrib: contributed code that is not mature enough (SpinImages, Chamfer distance, ) legacy: obsolete code, preserved for backward compatibility
Operazioni (un po più) avanzate Possibilità limitate di strumenti per l interazione utente e per gestione di Graphical User Interfaces Versione pre 2.2: Creazione di trackbars per modificare parametri (HighGui) Cattura click del mouse sulle immagini (HighGui) Stampa testo su immagini Versione 2.2 ma ancora sperimentale: Qt backend for OpenCV text rendering using TTF fonts, separate "control panel" with sliders, push-buttons, checkboxes and radio buttons interactive zooming, panning of the images displayed in highgui windows, save as, etc Per il progetto finale, per chi è interessato (facoltativo!) : Microsoft Foundation Classes (MFC), Java,
How to get Help! Nella cartella di installazione: /doc/opencv.pdf Descrizione (più o meno) completa di ciascuna funzione della libreria Forum su Yahoo Groups: http://tech.groups.yahoo.com/group/opencv/ È possibile porre delle domande sul forum (sperando che qualcuno risponda)
OpenCV pre 2.2 e VisualStudio Per installare e utilizzare OpenCV su VisualStudio 2005: Una tantum: Tools ->Options -> Projects and Solutions -> VC++ Directories: Include files: PATH\OpenCV\otherlibs\highgui PATH\OpenCV\cxcore\include PATH\OpenCV\cvaux\include PATH\OpenCV\cv\include (PATH\OpenCV\otherlibs\cvcam\include) Library files: PATH\OpenCV\lib Ad ogni nuovo progetto: Specificare i file.lib di OpenCV. In Project -> Properties, selezionare la scheda Configuration Properties -> Linker -> Input e aggiungere nel campo Additional dependencies una stringa del tipo: cv.lib cvaux.lib cxcore.lib highgui.lib Aggiungere i comandi di #include degli header di OpenCV all inizio del codice che viene compilato nel progetto. Ad esempio: #include highgui.h #include cv.h #include cxcore.h #include cvaux.h ( #include cvcam.h ) Includere le DLL necessarie nella directory dell eseguibile
OpenCV 2.2 e VisualStudio Per installare e utilizzare OpenCV 2.2 su VisualStudio 2005/2010: Ad ogni nuovo progetto: Aggiungere la cartella include di OpenCV alle include directories. In Project -> Properties, selezionare la scheda Configuration Properties -> C/C++ -> General e aggiungere nel campo Additional Include Directories una stringa del tipo: ROOT_OPENCV\include Aggiungere la cartella libs di OpenCV alle include directories. In Project -> Properties, selezionare la scheda Configuration Properties -> C/C++ -> General e aggiungere nel campo Additional Include Directories una stringa del tipo: ROOT_OPENCV\lib Specificare le libreire di OpenCV necesarie. In Project -> Properties, selezionare la scheda Configuration Properties -> Linker -> Input e aggiungere nel campo Additional dependencies una stringa del tipo: opencv_core220.lib opencv_imgproc220.lib opencv_highgui220.lib Aggiungere il comando di #include del header di OpenCV all inizio del codice che viene compilato nel progetto. Ad esempio: #include opencv2/opencv.hpp Includere le DLL necessarie nella directory dell eseguibile Oppure includere il percorso che le contiene nella variabile PATH (dire sì quando l installante lo richiede)
IplImage Struttura dati di base di OpenCV Deriva dalle ipl (Intel Image Processing Library ora non più utilizzate) Contenuta in CxCore (pre 2.2) / opencv_core (2.2) Tutte le informazioni necessarie sono contenute sul doc di CxCore/core
Accesso agli elementi dell immagine Immagini: bidimensionali, ma memorizzate come vettori monodimensionali: (imagename -> imagedata)[index] Necessario un cast, in quanto in IplImage il campo imagedata è definito come char *: ((datatype *) (imagename -> imagedata)) [index] h w 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Rappresentazione logica 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 riga 2 riga 3 riga 4 riga Rappresentazione fisica Accesso ai dati in lettura/scrittura tramite un unico indice: (row-1) * w + (column-1) Es. : elemento in 3 riga, 2 colonna (n 9) : 2 * w + 1 = 2 * 4 + 1 = 9
Accesso agli elementi dell immagine (2) Nel caso IplImage: WidthStep non sempre coincide con Width. Occorre sempre utilizzare WidthStep quando si fa indicizzazione dell array dati di una IplImage. h w ws 0 1 2 p 3 4 5 p 6 7 8 p 9 10 11 p Es: immagine 3x4 = 12 elementi; h= 4, w = 3, ws = 4. Aggiunta una colonna di padding per l allineamento in memoria delle righe dell immagine. Per accedere all elemento 7 dell immagine (in coordinate: (r,c) = (3,2) ): usando Width: 2*w + 1 accedo all elemento in rosso (senza significato) usando WidthStep: 2*ws + 1 accedo all elemento in verde (corretto)
Accesso agli elementi dell immagine (3) Accesso con un unico indice è adatto solo per immagini che contengono byte Hanno profondità IPL_DEPTH_8U, IPL_DEPTH_8S Un metodo di accesso valido per ogni tipo di immagine è invece il seguente ((datatype *) (imagename -> imagedata + (row-1)*ws)) [col-1] Stesso esempio di prima, con dati short (2 byte per dato) p h w 0 1 2 p 3 4 5 p 6 7 8 p 9 10 11 p ws Es: immagine 3x4 = 12 elementi; h= 4, w = 3, ws = 8 (è in byte). short* p = ((short*) (imagename -> imagedata + 2*ws)) p[1] è il dato richiesto
Accesso agli elementi dell immagine (4) Immagini a colori hanno 3 canali: Blue, Green, Red(BGR). I canali sono memorizzati in maniera interleaved h w 0 1 2 3 4 5 6 7 0 1 2 3 8 9 10 11 4 5 6 7 0 1 2 12 3 13 14 15 8 9 10 11 4 5 6 7 12 13 14 15 8 9 10 11 12 13 14 15 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 1 riga 2 riga Rappresentazione fisica Rappresentazione logica Per accedere ad un colore di un pixel, bisogna moltiplicare per 3 l indice di riga e aggiungere l offset giusto B: ((datatype *) (imagename -> imagedata + (row-1)*ws)) [3*(col-1)] G: ((datatype *) (imagename -> imagedata + (row-1)*ws)) [3*(col-1)+1] R: ((datatype *) (imagename -> imagedata + (row-1)*ws)) [3*(col-1)+2]
cv::mat Struttura dati di base di OpenCV 2.2 E una classe C++ contenuta nel namespace cv E dotata di costruttori e operatori di cast per convertire da e verso IplImage. Tutte le informazioni necessarie sono contenute nel C++ cheatsheet /doc/opencv_cheatsheet.pdf Organizzazione in memoria identica ad IplImage widthstep rimpiazzato da step, width da cols, height da rows Accesso al pixel ((datatype *) (imagename -> data + (col-1)*step)) [(row-1)] oppure imagename->at<datatype>(row-1, col-1); La memoria è rilasciata automaticamente dal distruttore
cv::mat Le operazioni di algebra lineare sono realizzate ridefinendo gli operatori, è quindi possibile scrivere codice «alla MATLAB» cv::mat A(3,3,CV_8UC1); cv::mat B(3,3,CV_8UC1); cv::mat C = A B; // Esegue sottrazione elemento per elemento C = 255 A; // Vecchia memoria di C deallocata, nuova matrice creata ed ogni elemento inizializzato con 255 meno il corrispondente di A C = cv::abs(2*a cv::min(b)); // Vecchia memoria di C deallocata, nuova matrice creata ed ogni elemento inizializzato con il valore assoluto di 255 per il corrispondente di A meno il minimo elemento di B, saturazioni gestite in automatico //Risolvere un sistema lineare con la matrice pseudo-inversa Mat x = (A.t()*A).inv()*(A.t()*b);
Esercizio 1 invert grey Costruire il negativo di una immagine in scala di grigi Data una immagine in scala di grigi (range di ciascun pixel: [0 255]), sostituire ad ogni pixel di intensità I il valore (255-I)
Esercizio 2 invert RGB Come prima, ma in questo caso l immagine della quale si vuole costruire il negativo è a colori L immagine è formata da 3 canali (al contrario del caso precedente, riconducibile al caso di un singolo canale), relativi ai 3 valori RGB L intensità su ciascun canale assume un valore compreso nel range [0 255] Per ogni pixel dell immagine è dunque necessario sostituire la tripletta (B,G,R) con la sua inversa (255-B, 255-G, 255-R)
Esercizio 3 Image difference Realizzare un nuovo progetto VisualStudio che esegua le seguenti operazioni: 1. Apertura di 2 immagini (Immagine 1, I 1 e Immagine 2, I 2 ) 2. Calcolo della differenza tra le 2 immagini: costruire una immagine di output in cui ogni pixel di coordinate (x,y) è la differenza (in valore assoluto) dei corrispondenti pixel di I 1 e I 2 : Out(x,y) = abs(i 1 (x,y) I 2 (x,y)) 3. Visualizzazione sullo schermo dell immagine di output