OPENCV 1. INTRODUZIONE OpenCV è una libreria open source in C++ per l'image processing e la computer vision La libreria è costituita da funzioni principalmente progettate per l'elaborazione di immagini in tempo reale e sfrutta algoritmi specifici per rendere tale computazione semplice ed efficace. 2. INSTALLAZIONE (su Ubuntu) Da terminale è necessario digitare i seguenti comandi, come specificato all'indirizzo [1]. sudo apt-get install libopencv-dev sudo apt-get install build-essential checkinstall cmake pkg-config yasm sudo apt-get install libtiff4-dev libjpeg-dev libjasper-dev sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev libxine-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev sudo apt-get install python-dev python-numpy sudo apt-get install libtbb-dev sudo apt-get install libqt4-dev libgtk2.0-dev Listato 2.1 Successivamente è necessario scaricare OpenCV dal sito ufficiale [2], poi: tar -xvf OpenCV-2.4.0.tar.bz2 cd OpenCv-2.4.0/ mkdir build cd build cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_QT=ON -D WITH_XINE=ON -D WITH_OPENGL=ON -D WITH_TBB=ON -D BUILD_EXAMPLES=0N.. make sudo make install Listato 2.2 3. CONFIGURAZIONE IN NETBEANS a) nuovo progetto applicazione c++ b) tasto destro sul nuovo progetto proprietà build c++ compiler, aggiungere sotto include directories : /usr/local/include/opencv c) fare lo stesso per c compiler d) build Linker aggiunere sotto additional library directories : /usr/local/lib e) build Linker Libraries pkg config select opencv
Figura 3.1 4. BASI DI OPENCV 4.1 I moduli di opencv OpenCV ha una struttura modulare. I moduli principali di opencv sono i seguenti: a) core: è il modulo base di opencv. Include le strutture dati fondamentali (es. Mat) e le funzioni fondamentali per l'elaborazione delle immagini. b) highgui: questo modulo gestisce l'interfaccia utente, le codifiche di diversi video e immagini, la manipolazione delle finestre, le barre di scorrimento, gli eventi del mouse e altro. Per gestioni più avanzate si può fare riferimento a Qt, WinForms etc. c) imgproc: questo modulo include algoritmi fondamentali per l'elaborazione delle immagini come i filtri, le trasformazioni, le conversioni di colore etc. d) video: consente di analizzare i video attraverso algoritmi di tracking degli oggetti, di sottrazione dello sfondo etc. e) objdetect: include algoritmi per il riconoscimento di oggetti (object detection) f) Altri moduli 5. APPLICAZIONI Il codice presente nelle varie sezioni necessita dell'inclusione di alcune librerie. Le librerie più frequenti sono quelle presenti nel Listato 5.a (nel caso fossero necessarie ulteriori librerie da aggiungere verrà specificato nei successivi listati). Nel Listato 5.b è presente la struttura base del codice: nei successivi listati verrà presentata solo la funzione
specifica per l'argomento da trattare, per cui si dovrà sostituire in my_function il nome della funzione volta presa in considerazione. di volta in #include <cstdlib> #include <opencv/cv.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/video/video.hpp> #include <iostream> #include <stdio.h> Using Namespace cv; Listato 5.a int my_function(); int returning_value = 0; int main(int argc, char** argv) { returning _value = my_function(); int my_function(){ Listato 5.b 5.1 CREAZIONE FINESTRA void show_hello_world(){ cvnamedwindow( "My Window", 1 ); IplImage *img = cvcreateimage( cvsize( 640, 480 ), IPL_DEPTH_8U, 1 ); CvFont font; double hscale = 1.0; double vscale = 1.0; int linewidth = 1; cvinitfont( &font, CV_FONT_HERSHEY_SIMPLEX CV_FONT_ITALIC, hscale, vscale, 0, linewidth ); cvputtext( img, "Hello World!, I can now code opencv ", cvpoint( 0, 200 ), &font, cvscalar( 255, 255, 0 ) ); cvshowimage( "My Window", img ); cvwaitkey(); Listato 5.1.1
Figura 5.1.1 5.2 VISUALIZZAZIONE DI UNA IMMAGINE int show_image(){ Mat img = imread("sonic.jpg", CV_LOAD_IMAGE_UNCHANGED); if (img.empty()){ cout << "Error : Image cannot be loaded..!!" << endl; system("pause"); namedwindow("mywindow", CV_WINDOW_AUTOSIZE); imshow("mywindow", img); waitkey(0); destroywindow("mywindow"); returning_value = 0; Listato 5.2.1 5.3 VISUALIZZAZIONE DI UN VIDEO Figura 5.2.1
int show_movie(){ VideoCapture cap("panda.mp4"); // open the video file for reading if (!cap.isopened() ){ cout << "Cannot open the video file" << endl; double fps = cap.get(cv_cap_prop_fps); cout << "Frame per seconds : " << fps << endl; namedwindow("myvideo",cv_window_autosize); while(1){ Mat frame; bool bsuccess = cap.read(frame); if (!bsuccess){ cout << "Cannot read the frame from video file" << endl; break; imshow("myvideo", frame); if(waitkey(30) == 27) { cout << "esc key is pressed by user" << endl; break; Listato 5.3.1 5.4 GENERAZIONE DI UN FILE (IMMAGINE) Figura 5.3.1 int write_image_to_file(){ Mat img(400, 400, CV_16UC3, Scalar(50000,0,0)); //Scalar(blue,green,red) from 0 to 50000 if (img.empty()){ cout << "ERROR : Image cannot be loaded..!!" << endl; system("pause"); vector<int> compression_params; compression_params.push_back(cv_imwrite_jpeg_quality); compression_params.push_back(98); bool bsuccess = imwrite("mytest.jpg", img, compression_params); if (!bsuccess ){ cout << "ERROR : Failed to save the image" << endl;
system("pause"); namedwindow("mywindow", CV_WINDOW_AUTOSIZE); imshow("mywindow", img); waitkey(0); destroywindow("mywindow"); Listato 5.4.1 Figura 5.4.1 5.5 FILTRAGGIO modifica della luminosità di una immagine E' una operazione puntuale (una operazione puntuale coinvolge ogni singolo pixel dell'immagine per l'elaborazione dell'immagine di output). Per incrementare/decrementare la luminosità viene aggiunto/sottratto un determinato valore costante ad ogni pixel dell'immagine: new_img ( i, j ) = img ( i, j ) + c incremento new_img ( i, j ) = img ( i, j ) + c decremento Bisogna tener presente che nel decremento, i pixel non possono avere valore negativo (la luminosità più bassa è pari a zero, che corrisponde al colore nero), per cui i valori negativi vengono posti a zero. int change_brightness(){ Mat img = imread("me.jpg", CV_LOAD_IMAGE_COLOR); if (img.empty()){ cout << "Image cannot be loaded..!!" << endl; Mat imgh = img + Scalar(75, 75, 75); //incremento di 75 unità //img.convertto(imgh, -1, 1, 75); Mat imgl = img + Scalar(-75, -75, -75); //decremento di 75 unità //img.convertto(imgl, -1, 1, -75); namedwindow("original Image", CV_WINDOW_AUTOSIZE); namedwindow("high Brightness", CV_WINDOW_AUTOSIZE); namedwindow("low Brightness", CV_WINDOW_AUTOSIZE); imshow("original Image", img); imshow("high Brightness", imgh); imshow("low Brightness", imgl); waitkey(0); destroyallwindows();
Listato 5.5.1 Figura 5.5.1 immagine originale Figura 5.5.2 alta luminosità Figura 5.5.3 bassa luminosità modifica del contrasto di una immagine Anche la modifica del contrasto è una operazione puntuale. Uno dei modi per modificare il contrasto è moltiplicare ogni pixel per un determinato valore che sarà maggiore di 1 nel caso si voglia evidenziale il contrasto, e minore di 1 nel caso si voglia diminuire: new_img (i, j) = img(i, j) * c (c > 1) incremento new_img (i, j) = img(i, j) * c (c < 1) decremento int change_image_contrast(){ Mat img = imread("me.jpg", CV_LOAD_IMAGE_COLOR); //open and read the image if (img.empty()){ cout << "Image cannot be loaded..!!" << endl; Mat imgh; img.convertto(imgh, -1, 2, 0); //increase the contrast (double) Mat imgl; img.convertto(imgl, -1, 0.5, 0); //decrease the contrast (halve) //create windows namedwindow("original Image", CV_WINDOW_AUTOSIZE); namedwindow("high Contrast", CV_WINDOW_AUTOSIZE); namedwindow("low Contrast", CV_WINDOW_AUTOSIZE); //show the image imshow("original Image", img); imshow("high Contrast", imgh); imshow("low Contrast", imgl); waitkey(0); //wait for key press destroyallwindows(); //destroy all open windows Listato 5.5.2
Figura 5.5.4 immagine originale Figura 5.5.5 alto contrasto Figura 5.5.6 basso contrasto 5.5.3 istogramma di una immagine in scala di grigi o di una immagine colorata Un istogramma è la distribuzione di intensità di una immagine. Il pareggiamento dell'istogramma (equalization) è definito come il pareggiamento della distribuzione di intensità di una immagine e viene in genere utilizzato per migliorare il contrasto di una immagine. Questa funzionalità è disponibile in OpenCV. caso immagine in scala di grigio int equalize_bw_image(){ Mat img = imread("redpanda.jpg", CV_LOAD_IMAGE_COLOR); if (img.empty()){ cout << "Image cannot be loaded..!!" << endl; cvtcolor(img, img, CV_BGR2GRAY); Mat img_hist_equalized; equalizehist(img, img_hist_equalized); namedwindow("original Image", CV_WINDOW_AUTOSIZE); namedwindow("histogram Equalized", CV_WINDOW_AUTOSIZE); imshow("original Image", img); imshow("histogram Equalized", img_hist_equalized); waitkey(0); destroyallwindows();
caso immagine a Figura 5.5.7 Figura 5.5.8 colori int equalize_cl_image(){ Mat img = imread("redpanda2.jpg", CV_LOAD_IMAGE_COLOR); //open and read the image if (img.empty()){ cout << "Image cannot be loaded..!!" << endl; vector<mat> channels; Mat img_hist_equalized; cvtcolor(img, img_hist_equalized, CV_BGR2YCrCb); split(img_hist_equalized,channels); equalizehist(channels[0], channels[0]); merge(channels,img_hist_equalized); cvtcolor(img_hist_equalized, img_hist_equalized, CV_YCrCb2BGR); namedwindow("original Image", CV_WINDOW_AUTOSIZE); namedwindow("histogram Equalized", CV_WINDOW_AUTOSIZE); imshow("original Image", img); imshow("histogram Equalized", img_hist_equalized); waitkey(0); Listato 5.5.4 Figura 5.5.9 Figura 5.5.10
immagini smooth / blur Questa tecnica mira generalmente alla riduzione di rumore. Esistono vari metodi per realizzare questa tecnica: a) smooth omogeneo b) smooth gaussiano c) smooth mediano d) smooth bilaterale Nel listato seguente è presentato il caso a) : int homogeneous_smooth(){ namedwindow( "Original Image", CV_WINDOW_AUTOSIZE ); namedwindow( "Smoothed Image", CV_WINDOW_AUTOSIZE ); Mat src = imread( "redpanda2.jpg", 1 ); imshow( "Original Image", src ); Mat dst; char zbuffer[35]; for ( int i = 1; i < 8; i = i + 2 ){ snprintf(zbuffer, 35,"Kernel Size : %d x %d", i, i); blur( src, dst, Size( i, i ) ); puttext( dst, zbuffer, Point( src.cols/4, src.rows/8), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) ); imshow( "Smoothed Image", dst ); int c = waitkey(2000); if (c == 27){ return 0; dst = Mat::zeros( src.size(), src.type() ); snprintf(zbuffer, 35,"Press Any Key to Exit"); puttext( dst, zbuffer, Point( src.cols/4, src.rows / 2), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) ); imshow( "Smoothed Image", dst ); waitkey(0); Listato 5.5.5 Figura 5.5.11 Figura 5.5.12 Trackbar int trackbar(){ Mat src = imread("panda.jpg"); if (!src.data) { cout << "Error loading the image" << endl;
namedwindow("my Window", 1); int islidervalue1 = 50; createtrackbar("brightness", "My Window", &islidervalue1, 100); int islidervalue2 = 50; createtrackbar("contrast", "My Window", &islidervalue2, 100); while (true){ Mat dst; int ibrightness = islidervalue1-50; double dcontrast = islidervalue2 / 50.0; src.convertto(dst, -1, dcontrast, ibrightness); imshow("my Window", dst); int ikey = waitkey(50); if (ikey == 27){ break; Listato 5.5.6 Figura 5.5.13 Figura 5.5.14
Controllo tramite mouse Nel Listato 5.7.1 è illustrato come rilevare le coordinate (x, y) del mouse (ovvero la sua posizione). In OpenCV è possibile anche individuare quanto vengono premuti i tasti del mouse, ma non verranno trattati di seguito. void CallBackFunc(int event, int x, int y, int flags, void* userdata){ if ( event == EVENT_LBUTTONDOWN ){ cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl; else if ( event == EVENT_RBUTTONDOWN ){ cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl; else if ( event == EVENT_MBUTTONDOWN ){ cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << endl; else if ( event == EVENT_MOUSEMOVE ){ cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl; int mouse_control(){ Mat img = imread("panda.jpg"); if ( img.empty() ) { cout << "Error loading the image" << endl; namedwindow("my Window", 1); setmousecallback("my Window", CallBackFunc, NULL); imshow("my Window", img); waitkey(0); Listato 5.5.7 Figura 5.5.15
Rilevamento del color e tracking dell'oggetto int color_tracking(){ VideoCapture cap(0); if (!cap.isopened() ){ cout << "Cannot open the web cam" << endl; return -1; namedwindow("control",cv_window_autosize); int ilowh = 0; int ihighh = 255; int ilows = 0; int ihighs = 255; int ilowv = 0; int ihighv = 255; cvcreatetrackbar("lowh", "Control", &ilowh, 255); cvcreatetrackbar("highh", "Control", &ihighh, 255); cvcreatetrackbar("lows", "Control", &ilows, 255); cvcreatetrackbar("highs", "Control", &ihighs, 255); cvcreatetrackbar("lowv", "Control", &ilowv, 255); cvcreatetrackbar("highv", "Control", &ihighv, 255); while (true){ Mat imgoriginal; bool bsuccess = cap.read(imgoriginal); if (!bsuccess){ cout << "Cannot read a frame from video stream" << endl; break; Mat imghsv; cvtcolor(imgoriginal, imghsv, COLOR_BGR2HSV); Mat imgthresholded; inrange(imghsv, Scalar(iLowH, ilows, ilowv), Scalar(iHighH, ihighs, ihighv), imgthresholded); dilate( imgthresholded, imgthresholded, getstructuringelement(morph_rect, Size(3, 3)) ); imshow("thresholded Image", imgthresholded); imshow("original", imgoriginal); if (waitkey(30) == 27){ cout << "esc key is pressed by user" << endl; break; Listato 5.5.8
Figura 5.5.16 Listato 5.8.2 Figura 5.5.17 Sovrapposizione di immagini int overlayimage(){ double alpha = 0.5; double beta; double input; Mat src1, src2, dst; std::cout<<" Simple Linear Blender "<<std::endl; std::cout<<"-----------------------"<<std::endl; std::cout<<"* Enter alpha [0-1]: ";
std::cin>>input; if( input >= 0.0 && input <= 1.0 ) { alpha = input; src1 = imread("myself.jpg"); src2 = imread("image.jpg"); if(!src1.data ) { printf("error loading src1 \n"); return -1; if(!src2.data ) { printf("error loading src2 \n"); return -1; namedwindow("sovrapposizione immagini in OpenCV", 1); beta = ( 1.0 - alpha ); addweighted( src1, alpha, src2, beta, 0.0, dst); imshow( "sovrapposizione immagini in OpenCV", dst ); waitkey(0); rvalue = 0; return rvalue; Rilevamento della forma & tracking usando i contorni Listato 5.5.9 Figura 5.5.18 6....
REFERENCES [1] OpenCV official website http://opencv.org/downloads.html [2] installation reference http://karytech.blogspot.it/2012/05/opencv-24-onubuntu-1204.html