diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..defa1cc14ad7faae17aa0b9cb1e8698d0ebcf20f --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +*.jpg +*.JPG +*.bin +bin/ diff --git a/omap3/traitementImages/Applatir/applatir.cpp b/omap3/traitementImages/Applatir/applatir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c67beaf428cd543e20a179ec304cdb22c4d2cf38 --- /dev/null +++ b/omap3/traitementImages/Applatir/applatir.cpp @@ -0,0 +1,132 @@ +#include "cv.h" +#include "highgui.h" + +#include +#include + +#define PI 3.14159265 + +using namespace cv; +using namespace std; + +int main(int argc, char** argv) { + int alpha_=90., beta_=90., gamma_=90.; + int f_ = 500, dist_ = 500; + bool video = false; + + Mat source, destination; + VideoCapture capture(0); + + if (argc >= 2) { + // Si au moins un argument est précisé, on essaye de charger l'image + cout << "Lecture de " << argv[1] << endl; + source = imread(argv[1]); + } else { + // Sinon on essaye d'ouvrir une capture de vidéo (webcam) + cout << "Ouverture du flux vidéo..." << endl; + if(!capture.isOpened()) { + cout << "... échec :(" << endl; + return -1; + } + cout << "... ça marche :)" << endl; + video = true; + } + + string wndname1 = "Source"; + string wndname2 = "Warp Perspective"; + string tbarname1 = "Alpha"; + string tbarname2 = "Beta"; + string tbarname3 = "Gamma"; + string tbarname4 = "f"; + string tbarname5 = "Distance"; + namedWindow(wndname1, 1); + namedWindow(wndname2, 1); + createTrackbar(tbarname1, wndname2, &alpha_, 180); + createTrackbar(tbarname2, wndname2, &beta_, 180); + createTrackbar(tbarname3, wndname2, &gamma_, 180); + createTrackbar(tbarname4, wndname2, &f_, 2000); + createTrackbar(tbarname5, wndname2, &dist_, 2000); + + + while(true) { + // Les trackbar d'opencv ne donnent que des valeurs entières entre 0 + // et le max (dernier paramètre de createTrackbar) + // Il faut donc adapter les paramètres + double f, dist; + double alpha, beta, gamma; + alpha = ((double)alpha_ - 90.)*PI/180; + beta = ((double)beta_ - 90.)*PI/180; + gamma = ((double)gamma_ - 90.)*PI/180; + f = (double) f_; + dist = (double) dist_; + + if (video) { + // Capture l'image de la caméra + capture >> source; + } + + // Affiche l'image + imshow(wndname1, source); + + Size taille = source.size(); + double w = (double)taille.width, h = (double)taille.height; + + // Cette matrice projette l'image de la caméra (2D) dans l'espace (3D) + // et la centre + Mat A1 = (Mat_(4,3) << + 1, 0, -w/2, + 0, 1, -h/2, + 0, 0, 0, + 0, 0, 1); + // On définit les 3 matrices de rotation (une par axe) + Mat RX = (Mat_(4, 4) << + 1, 0, 0, 0, + 0, cos(alpha), -sin(alpha), 0, + 0, sin(alpha), cos(alpha), 0, + 0, 0, 0, 1); + Mat RY = (Mat_(4, 4) << + cos(beta), 0, -sin(beta), 0, + 0, 1, 0, 0, + sin(beta), 0, cos(beta), 0, + 0, 0, 0, 1); + Mat RZ = (Mat_(4, 4) << + cos(gamma), -sin(gamma), 0, 0, + sin(gamma), cos(gamma), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + // La matrice de rotation finale + Mat R = RX * RY * RZ; + // Matrice de translation : on place le plan à la distance "dist" de + // la caméra + Mat T = (Mat_(4, 4) << + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, dist, + 0, 0, 0, 1); + // Matrice de la caméra : projette l'image en 2D et la centre + Mat A2 = (Mat_(3,4) << + f, 0, w/2, 0, + 0, f, h/2, 0, + 0, 0, 1, 0); + // La matrice de transformation est tout simplement le produit des + // matrices + Mat transfo = A2 * (T * (R * A1)); + + // Applique la transformation + warpPerspective(source, destination, transfo, taille, INTER_CUBIC | WARP_INVERSE_MAP); + // Affiche le résultat + imshow(wndname2, destination); + + if (video) { + // Quitte lorsqu'une touche est pressée + if(waitKey(10) >= 0) + break; + } else { + // Quitte lorsque la touche echap est pressée + if(waitKey(0) == 27) + break; + } + } + + return 0; +} diff --git a/omap3/traitementImages/Applatir/makefile b/omap3/traitementImages/Applatir/makefile new file mode 100644 index 0000000000000000000000000000000000000000..a63bf3073f563b5a69f71ef5da99c0ed366782ff --- /dev/null +++ b/omap3/traitementImages/Applatir/makefile @@ -0,0 +1,17 @@ +CC=g++ +CFLAGS=-c -Wall -g -O0 `pkg-config opencv --cflags` +LDFLAGS=`pkg-config opencv --libs` +SOURCES=applatir.cpp +OBJECTS=$(SOURCES:.cpp=.o) +EXECUTABLE=applatir.bin + +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +.cpp.o: + $(CC) $(CFLAGS) $< -o $@ + +clean: + rm *.o diff --git a/omap3/traitementImages/GetColor/getColor.cpp b/omap3/traitementImages/GetColor/getColor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c85037fcfa1850c3b08f8410108e3b5de0336a4 --- /dev/null +++ b/omap3/traitementImages/GetColor/getColor.cpp @@ -0,0 +1,138 @@ + + +// include standard OpenCV headers, same as before +#include +#include +#include +#include +#include +#include "cv.h" +#include "highgui.h" + +// all the new API is put into "cv" namespace. Export its content +using namespace cv; +using namespace std; + +// enable/disable use of mixed API in the code below. +#define DEMO_MIXED_API_USE 1 + +#define CV_EVENT_MOUSEMOVE 0 +#define CV_EVENT_LBUTTONDOWN 1 +#define CV_EVENT_RBUTTONDOWN 2 +#define CV_EVENT_MBUTTONDOWN 3 +#define CV_EVENT_LBUTTONUP 4 +#define CV_EVENT_RBUTTONUP 5 +#define CV_EVENT_MBUTTONUP 6 +#define CV_EVENT_LBUTTONDBLCLK 7 +#define CV_EVENT_RBUTTONDBLCLK 8 +#define CV_EVENT_MBUTTONDBLCLK 9 + +int h = 0, s = 0, v = 0, tolerance = 40; +IplImage *image; + +void my_mouse_callback( int event, int x, int y, int flags, void *param=NULL) +{ + + CvScalar pixel; + + + +if(event== CV_EVENT_LBUTTONDOWN ) + { + + pixel=cvGet2D(image,y,x); + + + printf("\nB=%f, G=%f R=%f",pixel.val[0],pixel.val[1],pixel.val[2]); + + h = (int)pixel.val[0]; + s = (int)pixel.val[1]; + v = (int)pixel.val[2]; + + + } + + + +} + + +int main( ) +{ + + const char* imagename = "1.jpg"; + //const char* imagename = "1.jpg"; + + IplImage *img = cvLoadImage(imagename); + if(!img) + { + printf("Erreur \n"); + return -1; + + } + //Largueur image dans pixels + int width = img->width; + //Hauture image dans pixels + int height = img->height; + int step = img->widthStep/sizeof(uchar); + + //Nombre canaux image + int channels = img->nChannels; + + + + +//Binarisation +int x, y; +CvScalar pixel; +IplImage *img_s,*hsv, *detec,*mask,*hsv_s, *mask_s, *image_new, *image_new2, *gray; +IplConvKernel *kernel; +int sommeX = 0, sommeY = 0; +int nbPixels = 0, nbPixels2 = 0; +// Key for keyboard event +char key=0; + + + +//uchar* data = (uchar *)img->imageData; //cargamos los datos de la imagen en “data” + + +printf("\nstep=%d height=%d",step, height); +fflush(stdout); + +//image = cvCloneImage(img); + +cvNamedWindow("original", CV_WINDOW_AUTOSIZE); +cvShowImage("original", img); + + +image= cvCloneImage(img); + +// Set up the callback +//cvSetMouseCallback("original_hsv", my_mouse_callback, (void*) image_hsv); //original_hsv + +//FONCTION QUI DETECTE LES COULEURS RGB +cvSetMouseCallback("original", my_mouse_callback, (void*) image); //original + + + while(1/*key != 'Q' && key != 'q'*/) + { + + + // We wait 10 ms + key = cvWaitKey(10); + + } + + + +cvReleaseImage( &img ); + +cvDestroyWindow("original"); + +cvWaitKey(10); + +return 0; + + +} diff --git a/omap3/traitementImages/GetColor/makefile b/omap3/traitementImages/GetColor/makefile new file mode 100644 index 0000000000000000000000000000000000000000..941b41911c25a62adb8169afe90e9e383af82137 --- /dev/null +++ b/omap3/traitementImages/GetColor/makefile @@ -0,0 +1,16 @@ +CC=g++ +CFLAGS=-c -Wall -g -O0 `pkg-config opencv --cflags` +LDFLAGS=`pkg-config opencv --libs` +SOURCES=getColor.cpp +OBJECTS=$(SOURCES:.cpp=.o) +EXECUTABLE=Color.bin +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +.cpp.o: + $(CC) $(CFLAGS) $< -o $@ + +clean: + rm *.o diff --git a/omap3/traitementImages/TestCPP/TestCPP.cbp b/omap3/traitementImages/TestCPP/TestCPP.cbp new file mode 100644 index 0000000000000000000000000000000000000000..71b579189cb8f5666e0d281e893d370a74041dc4 --- /dev/null +++ b/omap3/traitementImages/TestCPP/TestCPP.cbp @@ -0,0 +1,43 @@ + + + + + + diff --git a/omap3/traitementImages/TestCPP/TestCPP.depend b/omap3/traitementImages/TestCPP/TestCPP.depend new file mode 100644 index 0000000000000000000000000000000000000000..6187e5a5e8ee5a4f94ef1d894b13c8038bc5495c --- /dev/null +++ b/omap3/traitementImages/TestCPP/TestCPP.depend @@ -0,0 +1,11 @@ +# depslib dependency file v1.0 +1302210822 source:/home/mohamed/ProjetS4/TestCPP/main.cpp + + + + +1302191236 source:/home/mohamed/ProjetS4/TestCPP/math.cpp + "math.h" + +1302191489 /home/mohamed/ProjetS4/TestCPP/math.h + diff --git a/omap3/traitementImages/TestCPP/TestCPP.layout b/omap3/traitementImages/TestCPP/TestCPP.layout new file mode 100644 index 0000000000000000000000000000000000000000..c760e45544fc86fa7e9aef33f034b242c6fcc7f9 --- /dev/null +++ b/omap3/traitementImages/TestCPP/TestCPP.layout @@ -0,0 +1,7 @@ + + + + + + + diff --git a/omap3/traitementImages/TestCPP/main.cpp b/omap3/traitementImages/TestCPP/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0b521c56934796b97e5892f478b1770136fd7b3 --- /dev/null +++ b/omap3/traitementImages/TestCPP/main.cpp @@ -0,0 +1,36 @@ +#include +# include +#include +#include + +using namespace std; + +string desordonner(string mot) +{ + srand(time(0)); + int l(mot.size()); + string motDesordonne(""); + while (l!=0) + { + int position=rand() % l; + motDesordonne+=mot[position]; + mot.erase(position,1); + l=mot.size(); + } + return motDesordonne; +} + + +int main() +{ + int *pointeur(0); + pointeur=new int; + cout << "quel est votre age ?"<< endl; + cin >> *pointeur; + cout << "votre age est : " << *pointeur << endl; + delete pointeur; + pointeur=0; + return 0; +} + + diff --git a/omap3/traitementImages/TestCPP/math.cpp b/omap3/traitementImages/TestCPP/math.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5999b7629244baadfc71327d0318d6ab955ee81b --- /dev/null +++ b/omap3/traitementImages/TestCPP/math.cpp @@ -0,0 +1,8 @@ +#include "math.h" + +int ajouteDeux(int nombreRecu) +{ + int valeur(nombreRecu + 2); + + return valeur; +} diff --git a/omap3/traitementImages/TestCPP/math.h b/omap3/traitementImages/TestCPP/math.h new file mode 100644 index 0000000000000000000000000000000000000000..16a72154a5a831f7f21fe3d8cdf938b88c4cd8dd --- /dev/null +++ b/omap3/traitementImages/TestCPP/math.h @@ -0,0 +1,6 @@ +#ifndef MATH_H_INCLUDED +#define MATH_H_INCLUDED + +int ajouteDeux(int nombreRecu); + +#endif // MATH_H_INCLUDED diff --git a/omap3/traitementImages/TestCPP/monTexte.txt b/omap3/traitementImages/TestCPP/monTexte.txt new file mode 100644 index 0000000000000000000000000000000000000000..54d7e9be01a3238a79e045846625332a2c679dcf --- /dev/null +++ b/omap3/traitementImages/TestCPP/monTexte.txt @@ -0,0 +1,5 @@ +moi benjelloun mohamed +j'ai 22 ans ! +je suis beaugoss. moi benjelloun amine +j'ai 16 ans ! +je suis beaugoss. \ No newline at end of file diff --git a/omap3/traitementImages/Vision/Vision.cpp b/omap3/traitementImages/Vision/Vision.cpp new file mode 100644 index 0000000000000000000000000000000000000000..21d6d3881d963af615e7fc34b7971a594408f09b --- /dev/null +++ b/omap3/traitementImages/Vision/Vision.cpp @@ -0,0 +1,310 @@ +#include "cv.h" +#include "highgui.h" + +#include +#include +#include +#include +#include + +#define PI 3.14159265 + +using namespace cv; +using namespace std; + + + +// les paramètres pour applatir l'image reçue de la camèra. +// A regler selon la position de la camera sur le robot ! +int alpha_=30., beta_=90., gamma_=90.; +int f_ = 500, dist_ =415; + +// les parametres ci-dessous dependent de la resolution de la camera, des parametres pour applatir. +// ils servent a faire le lien entre la distance reelle sur la table et la distance mesure sur l'image. +// et aussi de detecter les cercles avec précision + +double dminCentres=40.; // la distance minimale entre les centres des cercles a detecter. +int rayonMin=13; // le rayon minimal des cercles a detecter. +int rayonMax=192; // le rayon maximal des cercles a detecter + +int coteCase=350; // en mm, chaque case a une longueur de 100 pixels donc chaque pixel represente 3,5 mm. + +// cette fonction prend en argument une matrice de 0 et de 1, +// et retourne si le pourcentage des "1" est superieur à la valeur pourcentage donnée en argument. +bool estBlanc(Mat rect,double pourcentage) { + bool estBlanc; + Size taille = rect.size(); + double w = (double)taille.width, h = (double)taille.height; + double nombreDesUns=countNonZero((Mat_)rect); + double pourcentageDesUns=nombreDesUns/(w*h); + if (pourcentageDesUns>=pourcentage) { + estBlanc=true; + } + else { + estBlanc=false; + } + return estBlanc; +} + + +//cette fonction dit si le point est à l'interieur du rectangle +bool estInterieur(Rect rectangle,Point point) { + double x=rectangle.x; + double y=rectangle.y; + double w=rectangle.width; + double h=rectangle.height; + if ((point.x>=x)&&(point.y>=y)&&(point.x<=x+w)&&(point.y<=y+h)) { + return true; + } + else return false; +} + +// cette fonction donne le type du pion observé : 0 un simple pion, 1 une tour. +int pion(double longueur) { + if (longueur<=20) + return 0; + else return 1; +} + +int main(int argc, char** argv) { + + + // indique si on a le flux video ou pas. + bool video = false; + + // source est l'image vu par la camèra. + // destination est l'image "vu" par le robot. + // contours1 est l'image obtenue apres detection de contours sur l'image en 3 channals. + // contours2 est l'image obtenue apres detection de contours sur l'image dans le channal G (Green). + // cercles1 est un vecteur contenant les coordonnées et rayons des cercles dans l'image contours1 + // cercles2 est un vecteur contenant les coordonnées et rayons des cercles dans l'image contours2 + Mat source, destination, contours1, contours2; + vector cercles1, cercles2; + VideoCapture capture(0); + + // lecture des donnees : + if (argc >= 2) { + // Si au moins un argument est précisé, on essaye de charger l'image + cout << "Lecture de " << argv[1] << endl; + source = imread(argv[1]); + } else { + // Sinon on essaye d'ouvrir une capture de vidéo (webcam) + cout << "Ouverture du flux vidéo..." << endl; + if(!capture.isOpened()) { + cout << "... échec :(" << endl; + return -1; + } + cout << "... ça marche :)" << endl; + video = true; + } + + // juste pour les tests sur ordinateur. + string wndname1 = "Source"; + string wndname2 = "destination"; + string wndname3 = "contours1"; + string wndname4 = "contours2"; + string wndname5 = "test"; + namedWindow(wndname1, 1); + namedWindow(wndname2, 1); + namedWindow(wndname3, 1); + namedWindow(wndname4, 1); + namedWindow(wndname5, 1); + + while(true) { + + // on transforme les angles en radians. + double f, dist; + double alpha, beta, gamma; + alpha = ((double)alpha_ - 90.)*PI/180; + beta = ((double)beta_ - 90.)*PI/180; + gamma = ((double)gamma_ - 90.)*PI/180; + f = (double) f_; + dist = (double) dist_; + + if (video) { + // Capture l'image de la caméra + capture >> source; + } + + // Affiche l'image + imshow(wndname1, source); + + Size taille = source.size(); + double w = (double)taille.width, h = (double)taille.height; + + // Cette matrice projette l'image de la caméra (2D) dans l'espace (3D) + // et la centre + Mat A1 = (Mat_(4,3) << + 1, 0, -w/2, + 0, 1, -h/2, + 0, 0, 0, + 0, 0, 1); + // On définit les 3 matrices de rotation (une par axe) + Mat RX = (Mat_(4, 4) << + 1, 0, 0, 0, + 0, cos(alpha), -sin(alpha), 0, + 0, sin(alpha), cos(alpha), 0, + 0, 0, 0, 1); + Mat RY = (Mat_(4, 4) << + cos(beta), 0, -sin(beta), 0, + 0, 1, 0, 0, + sin(beta), 0, cos(beta), 0, + 0, 0, 0, 1); + Mat RZ = (Mat_(4, 4) << + cos(gamma), -sin(gamma), 0, 0, + sin(gamma), cos(gamma), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + // La matrice de rotation finale + Mat R = RX * RY * RZ; + // Matrice de translation : on place le plan à la distance "dist" de + // la caméra + Mat T = (Mat_(4, 4) << + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, dist, + 0, 0, 0, 1); + // Matrice de la caméra : projette l'image en 2D et la centre + Mat A2 = (Mat_(3,4) << + f, 0, w/2, 0, + 0, f, h/2, 0, + 0, 0, 1, 0); + // La matrice de transformation est tout simplement le produit des + // matrices + Mat transfo = A2 * (T * (R * A1)); + + // Applique la transformation + warpPerspective(source, destination, transfo, taille, INTER_CUBIC | WARP_INVERSE_MAP); + // Affiche le résultat + imshow(wndname2, destination); + + // le traitement + + // on construit contours1, l'image contenant les contours de l'image destination (en 3 channals) + // et on construit aussi l'image gray : c'est l'image "destination" en noir et blanc. + cvtColor(destination, contours1, CV_BGR2GRAY); + GaussianBlur(contours1, contours1, Size(5,5), 1.5, 1.5); + Canny(contours1, contours1, 20, 50, 3,false); + Mat gray; + cvtColor(destination, gray, CV_BGR2GRAY); + + // on construit contours2, l'image contenant les contours de l'image destination dans le channal 1 (ie Green) + vector channels; + split(destination, channels); + GaussianBlur(channels[1], contours2, Size(5,5), 1.5, 1.5); + Canny(contours2, contours2, 20, 50, 3,false); + + // on consruit l'image Ggray : c'est l'image channels[1] (Vert) en noir et blanc. + // et Gray2, l'image channels[2] (Rouge) en noir et blanc + // et ensuite Ressemblance qui correspond à l'image ou le jaune dans "destination" est en blanc dans cette image et les autres couleurs sont en noir + // c est le vecteur contenant les contours dans l'image "Ressemblance" + Mat Ggray,Ggray2; + threshold(channels[1], Ggray, 172.,255., THRESH_BINARY); + threshold(channels[2], Ggray2, 172.,255., THRESH_BINARY); + Mat Ressemblance,contours3; + Ressemblance=((Ggray)&(Ggray2)); + GaussianBlur(Ressemblance, contours3, Size(5,5), 1.5, 1.5); + Canny(contours3, contours3, 20, 50, 3,false); + vector > c; + findContours(contours3, c, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + + // Detection des cercles dans les images contours1 et contours2, + HoughCircles(contours1,cercles1,CV_HOUGH_GRADIENT,2,dminCentres,600.,190.,rayonMin,rayonMax); + HoughCircles(contours2,cercles2,CV_HOUGH_GRADIENT,2,dminCentres,600.,190.,rayonMin,rayonMax); + + // Ces parametres dependent de la qualite de la camera, + // ils donnent les valeurs (en int) possibles des pixelx dont la couleur est celle des pions. + //int couleurPionsMax=2000000000; + //int couleurPionsMin=0; + + // puis on dessine chaque cercle (detecte dans contours2) dans destination en ne gardant que les pions, + // et on stocke le triplet (x,y,rayon) de ces pions dans le tableau pions. + // la matrice rect sert à eliminer les cercles parasites. + vector pions; + Mat rect; + + for( size_t i = 0; i < cercles2.size(); i++ ) + { + Point centre(cvRound(cercles2[i][0]), cvRound(cercles2[i][1])); + int rayon = cvRound(cercles2[i][2]); + + //on construit rect la matrice rectangle entourant le cercle i dans "Ressemblance", et on le transforme en une matrice de 0 et de 1, + getRectSubPix(Ressemblance, Size(2*rayon,2*rayon),centre,rect); + rect/=255.; + + // et on fait des conditions pour ne garder que les pions, ici on se base sur les couleurs, + // les valeurs des pixels sont détérminées par des tests sur plusieurs images, il faut les changer en fonction de la luminence de la table ! + if ((((Mat_)gray).at(centre)>104)&&(((Mat_)gray).at(centre)<248)&&(((Mat_)destination).at(centre)<218)&&(((Mat_)channels[0]).at(centre)>6)&&(((Mat_)channels[0]).at(centre)<182)&&(((Mat_)channels[2]).at(centre)>133)&&(((Mat_)channels[1]).at(centre)>103)&&(estBlanc(rect,0.25))){ + //if (estBlanc(rect,0.25)) { + + double hauteur=0; //c'est la hauteur du rectangle entourant le pion. + + // on cherche le rectangle entourant le pion, + for (size_t k=0; k= 0) + break; + } else { + // Quitte lorsque la touche echap est pressée + if(waitKey(0) == 27) + break; + } + } + + return 0; +} diff --git a/omap3/traitementImages/Vision/makefile b/omap3/traitementImages/Vision/makefile new file mode 100644 index 0000000000000000000000000000000000000000..50c4e484353252c088c47547c27c82db5286cf8a --- /dev/null +++ b/omap3/traitementImages/Vision/makefile @@ -0,0 +1,16 @@ +CC=g++ +CFLAGS=-c -Wall -g -O0 `pkg-config opencv --cflags` +LDFLAGS=`pkg-config opencv --libs` +SOURCES=Vision.cpp +OBJECTS=$(SOURCES:.cpp=.o) +EXECUTABLE=Vision.bin +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +.cpp.o: + $(CC) $(CFLAGS) $< -o $@ + +clean: + rm *.o diff --git a/omap3/traitementImages/Vision/seg.cpp b/omap3/traitementImages/Vision/seg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a5ab596ba564676eeeb9ea8947c4063db3088f22 --- /dev/null +++ b/omap3/traitementImages/Vision/seg.cpp @@ -0,0 +1,210 @@ +#include "cv.h" +#include "highgui.h" + +#include +#include +#include + + +#define PI 3.14159265 + +using namespace cv; +using namespace std; + +int main(int argc, char** argv) { + + // les paramètres pour applatir l'image reçue de la camèra. + // A regler selon la position de la camera sur le robot ! + int alpha_=30., beta_=90., gamma_=90.; + int f_ = 500, dist_ =415; + + // indique si on a le flux video ou pas. + bool video = false; + + // source est l'image vu par la camèra. + // destination est l'image "vu" par le robot. + // contours1 est l'image obtenue apres detection de contours sur l'image en 3 channals. + // contours2 est l'image obtenue apres detection de contours sur l'image dans le channal G (Green). + // lines1 est un vecteur contenant les coordonnées des extremites des segments detectes + + Mat source, destination, contours1, contours2; + vector lines1,lines2; + VideoCapture capture(0); + + // lecture des donnees : + if (argc >= 2) { + // Si au moins un argument est précisé, on essaye de charger l'image + cout << "Lecture de " << argv[1] << endl; + source = imread(argv[1]); + } else { + // Sinon on essaye d'ouvrir une capture de vidéo (webcam) + cout << "Ouverture du flux vidéo..." << endl; + if(!capture.isOpened()) { + cout << "... échec :(" << endl; + return -1; + } + cout << "... ça marche :)" << endl; + video = true; + } + + // juste pour les tests sur ordinateur. + string wndname1 = "Source"; + string wndname2 = "destination"; + string wndname3 = "contours1"; + string wndname4 = "contours2"; + string wndname5 = "test"; + namedWindow(wndname1, 1); + namedWindow(wndname2, 1); + namedWindow(wndname3, 1); + namedWindow(wndname4, 1); + namedWindow(wndname5, 1); + + Mat test=Mat_(40,40); + test=Scalar(0.,254.,255.); + cout << test.at(20,20)[1]<< endl; + imshow(wndname5, test); + + while(true) { + + // on transforme les angles en radians. + double f, dist; + double alpha, beta, gamma; + alpha = ((double)alpha_ - 90.)*PI/180; + beta = ((double)beta_ - 90.)*PI/180; + gamma = ((double)gamma_ - 90.)*PI/180; + f = (double) f_; + dist = (double) dist_; + + if (video) { + // Capture l'image de la caméra + capture >> source; + } + + // Affiche l'image + imshow(wndname1, source); + + Size taille = source.size(); + double w = (double)taille.width, h = (double)taille.height; + + // Cette matrice projette l'image de la caméra (2D) dans l'espace (3D) + // et la centre + Mat A1 = (Mat_(4,3) << + 1, 0, -w/2, + 0, 1, -h/2, + 0, 0, 0, + 0, 0, 1); + // On définit les 3 matrices de rotation (une par axe) + Mat RX = (Mat_(4, 4) << + 1, 0, 0, 0, + 0, cos(alpha), -sin(alpha), 0, + 0, sin(alpha), cos(alpha), 0, + 0, 0, 0, 1); + Mat RY = (Mat_(4, 4) << + cos(beta), 0, -sin(beta), 0, + 0, 1, 0, 0, + sin(beta), 0, cos(beta), 0, + 0, 0, 0, 1); + Mat RZ = (Mat_(4, 4) << + cos(gamma), -sin(gamma), 0, 0, + sin(gamma), cos(gamma), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + // La matrice de rotation finale + Mat R = RX * RY * RZ; + // Matrice de translation : on place le plan à la distance "dist" de + // la caméra + Mat T = (Mat_(4, 4) << + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, dist, + 0, 0, 0, 1); + // Matrice de la caméra : projette l'image en 2D et la centre + Mat A2 = (Mat_(3,4) << + f, 0, w/2, 0, + 0, f, h/2, 0, + 0, 0, 1, 0); + // La matrice de transformation est tout simplement le produit des + // matrices + Mat transfo = A2 * (T * (R * A1)); + + // Applique la transformation + warpPerspective(source, destination, transfo, taille, INTER_CUBIC | WARP_INVERSE_MAP); + // Affiche le résultat + imshow(wndname2, destination); + + + // le traitement + + // on construit contours1, l'image contenant les contours de l'image destination (en 3 channals) + cvtColor(destination, contours1, CV_BGR2GRAY); + Mat gray; + cvtColor(destination, gray, CV_BGR2GRAY); + GaussianBlur(contours1, contours1, Size(5,5), 1.5, 1.5); + Canny(contours1, contours1, 20, 50, 3,false); + + // on construit contours2, l'image contenant les contours de l'image destination dans le channal 1 ie Green + vector channels; + split(destination, channels); + GaussianBlur(channels[1], contours2, Size(5,5), 1.5, 1.5); + Canny(contours2, contours2, 20, 50, 3,false); + + IplImage *tranche,*src; + src= cvLoadImage("d.JPG"); + tranche = cvCreateImage(cvGetSize(src),src->depth , 1); + cvInRangeS(src,Scalar(0.,0.,0.),Scalar(0.,255.,0.),tranche); + imshow(wndname5,src); + imshow("test2",tranche); + + // les parametres ci-dessous dependent de la resolution de la camera, des parametres pour applatir. + // ils servent a faire le lien entre la distance reelle sur la table et la distance mesure sur l'image. + + double dminCentres=40.; // la distance minimale entre les centres des cercles a detecter. + int rayonMin=10; // le rayon minimal des cercles a detecter. + int rayonMax=200; // le rayon maximal des cercles a detecter + + + // Detection des cercles dans les images contours1 et contours2, + HoughLinesP(contours1,lines1, 1, CV_PI/180,1, 13, 5 ); + //HoughLinesP(contours2, lines2, 1, CV_PI/180, 80, 30, 10 );; + + // Ces parametres dependent de la qualite de la camera, + // ils donnent les valeurs (en int) possibles des pixelx dont la couleur est celle des pions. + int couleurPionsMax=2000000000; + int couleurPionsMin=0; + + // puis on dessine chaque cercle detecte dans contours2 en ne gardant que les pions, + // et on stocke le triplet (x,y,rayon) de ces pions dans le tableau pions. + vector pions; + + for( size_t i = 0; i < lines1.size(); i++ ) + { + line( destination, Point(lines1[i][0], lines1[i][1]), + Point(lines1[i][2], lines1[i][3]), Scalar(0,0,255), 3, 8 ); + + } + for( size_t i = 0; i < lines2.size(); i++ ) + { + line( destination, Point(lines2[i][0], lines2[i][1]), + Point(lines2[i][2], lines2[i][3]), Scalar(0,0,255), 3, 8 ); + + } + + imshow(wndname2, destination); + imshow(wndname3,contours1); + imshow(wndname4,contours2); + //cout <= 0) + break; + } else { + // Quitte lorsque la touche echap est pressée + if(waitKey(0) == 27) + break; + } + } + + return 0; +} diff --git a/omap3/traitementImages/code_sara/applatir.cpp b/omap3/traitementImages/code_sara/applatir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a31295bd825bfab311376a86c1f3bff2e9e0739 --- /dev/null +++ b/omap3/traitementImages/code_sara/applatir.cpp @@ -0,0 +1,235 @@ +//Matching avec cvMatchTemplate() +#include +#include +#include + +#include "cv.h" +#include "cxcore.h" +#include "highgui.h" +#include "iostream" +using namespace std; +using namespace cv; +/*enregistrez une image template en appuyant sur 'espace' +cette image sera recherchée dans la video issue de la webcam +matchtemplate retourne une valeur de corrélation pour chaque pixel de l'image +la valeur la plus grande de corrélation correspond très probablement au template recherché +pour un matching plus précis, il est possible de régler le seuil à partir duquel il y a matching +pour cela, observer dans la console la valeur maximale de corrélation pour chaque frame +puis agir sur la trackbar de seuil*/ + +int main() { + + //définition des images a utiliser + IplImage *src,*hsv,*mask;//=cvCreateImage(cvSize(640,480), 8, 3); + IplImage *templ;// = cvCreateImage(cvSize(200,300), 8, 3); + + templ = cvLoadImage("templ2.JPG"); + if(!templ) + { + printf("Erreur \n"); + return -1; + + } +src = cvLoadImage("img3.JPG"); +if(!src) + { + printf("Erreur \n"); + return -1; + + } +mask = cvCreateImage(cvGetSize(src),src->depth , 1); +hsv = cvCloneImage(src); +cvCvtColor(src, hsv, CV_BGR2HSV); + + + +cvInRangeS(hsv, cvScalar(9,80, 0), cvScalar(30,240,255),mask); + + +cvSaveImage("mascara.JPG",mask); +src = cvLoadImage("mascara.JPG"/*"mascara.JPG"*/);//src = cvLoadImage("img.JPG", 0); + if(!src) + { + printf("Erreur \n"); + return -1; + + } + + //définition de la taille(largeur, hauteur) de l'image ftmp + int iwidth = src->width - templ->width + 1; + int iheight = src->height - templ->height + 1; + IplImage *ftmp = cvCreateImage(cvSize(iwidth,iheight),IPL_DEPTH_32F,1); + + //seuil qui pourra être réglé avec un trackbar pour une détection plus pertinente + double seuil = 80.0; + //le trackbar n'acceptant que des valeurs entières on utilise 'seuil_int' + int seuil_int = (int) seuil; +//int center_x=0,center_y=0; +CvPoint min_loc_ant, max_loc_ant; +min_loc_ant.x=min_loc_ant.y=max_loc_ant.x=max_loc_ant.y=0; +CvPoint min_loc, max_loc; +min_loc_ant.x=min_loc_ant.y=max_loc_ant.x=max_loc_ant.y=2; + //définitions de points + CvPoint cadre_pt1 = cvPoint( (src->width - templ->width) / 2 , (src->height - templ->height) / 2); + CvPoint cadre_pt2 = cvPoint(cadre_pt1.x + templ->width , cadre_pt1.y + templ->height); + + + + /* CvCapture* capture = cvCreateCameraCapture( CV_CAP_ANY ); + if( !capture ) + return 1; + if(!cvGrabFrame( capture )) + return 2; + +*/int key=1; + + cvSmooth(src,src,CV_MEDIAN,3); + imshow("test",src); + + while (1/*(max_loc.x!=max_loc_ant.x) && (max_loc.y!=max_loc_ant.y) && (min_loc.x!=min_loc_ant.x) && (min_loc.x!=min_loc_ant.x)*/) + { + max_loc_ant.x=max_loc.x; + max_loc_ant.y=max_loc.y; + min_loc_ant.x=min_loc.x; + min_loc_ant.y=min_loc.y; + //si la touche 'échap' code ASCII '27' est appuyée, on quitte la boucle pour terminer le programme + if( key == 27 ) break; + + //capture les frames dans l'image 'src' + //src = cvRetrieveFrame( capture ); + + //applique le filtre médian pour réduire le bruit + // cvSmooth(src,src,CV_MEDIAN,3); + + //si la touche 'espace' code ASCII '32' est appuyée, on enregistre le template à partir de l'image 'src' + //le template est un rectangle 200*300 centré dans l'image 'src' + /* if (key == 32) + { + //dessine un rectangle noir autour de la zone qui est "photographiée" + cvRectangle(src, cadre_pt1,cadre_pt2, cvScalar(0,0,0)); + + //définition une région d'intérêt ROI + CvRect roi = cvRect (cadre_pt1.x,cadre_pt1.y,templ->width,templ->height); + + //fixe la ROI à l'image + cvSetImageROI(src,roi); + + //copie le rectangle sélectionné de 'src' à 'templ' + cvCopy(src,templ); + + // libérer la Region Of Interest de 'src' + cvResetImageROI(src); + }*/ + + cvMatchTemplate( src, templ, ftmp, 2);//trouver ce qui correspond à 'templ' dans 'src' + //src: l'image source capturée par la caméra + //templ: le template qui sera recherché dans l'image source + //ftmp: l'image qui contient le réultat du calcul + //CV_TM_CCOEFF_NORMED: la méthode de calcul utilisée ici permet un matching plus pertinent mais au prix de plus de calcul + + + //retrouver dans 'ftmp' les coordonnées du point ayant une valeur maximale + double min_val, max_val; + + cvMinMaxLoc(ftmp, &min_val, &max_val, &min_loc, &max_loc); + + //défnir un deuxième point à partir du premier point et de la taille de 'ftmp' + CvPoint max_loc2 = cvPoint(max_loc.x + templ->width, max_loc.y + templ->height);//définir le deuxième point en fonction de la taille du template + + //trackelfbar pour régler le seuil + cvCreateTrackbar( "seuil", "out", &seuil_int, 100, NULL ); + + // 'seuil' appartient à [0 1] alors que 'seuil_int' appartient à [0 100] donc: + seuil = (double) seuil_int / 100.0; + + //afficher la valeur maximale*100 de 'ftmp' pour chaque frame + cout << max_val*100 << "==="; + + //si la valeur maximale de 'ftmp' est supérieure au 'seuil' + //dessiner un rectangle rouge utilisant les coordonnées des deux points 'max_loc' et 'max_loc2' + if( max_val > seuil && max_val!=1 ) + { + cvRectangle(src, max_loc,max_loc2, cvScalar(0,0,255)); + printf("\nx1=%d x2_x=%d y1=%d y2=%d",max_loc.x,max_loc2.x,max_loc.y,max_loc2.y); + CvPoint centre; + if(max_loc.x>max_loc2.x) + + centre.x=max_loc2.x+41;//(int)((max_loc.x-max_loc2.x)/2); + else + centre.x=max_loc.x+41;(int)((max_loc2.x-max_loc.x)/2); + if(max_loc.y>max_loc2.y) + + centre.y=max_loc2.y+25;//(int)((max_loc.y-max_loc2.y)/2); + else + + centre.y=max_loc2.y+25;//(int)((max_loc2.y-max_loc.y)/2); + + printf("\ncentrexl=%d centrey=%d\n",centre.x,centre.y); + +float distance = 0; +int position=2;//0 gauche, 1 droite +CvPoint ptoref; +ptoref.x=((src->width)/2); +ptoref.y=((src->height)); +if(ptoref.x>centre.x) //figure a gauche +{ + position=0; + distance=sqrt(((ptoref.x-centre.x)*(ptoref.x-centre.x))+((ptoref.y-centre.y)*(ptoref.y-centre.y))); +} +else //figure a droite +{ + position=1; + distance=sqrt(((centre.x-ptoref.x)*(centre.x-ptoref.x))+((ptoref.y-centre.y)*(ptoref.y-centre.y))); +} +CvPoint position_new; +position_new.x=((src->height)-(centre.y)); +position_new.y=(centre.x-(src->width/2)); +float distance2=sqrt((position_new.x*position_new.x)+(position_new.y*position_new.y)); +printf("\n\ndistance1=%f distance2=%f",distance,distance2); +if(position==0) + printf("\nFigure detecté à gauche à une distance de %f dans les coordonnés[%d,%d]",distance,position_new.x,position_new.y); +else + printf("\nFigure detecté à droite à une distance de %f dans les coordonnés[%d,%d]",distance,position_new.x,position_new.y); + +/*int hauteur=350; +int alfa=15; +int d_horizontale=1000;//cm +int distance2=((350*cos30)/sin30); +*/ + + + + + + + + + + + + } + + + cvNamedWindow( "out", CV_WINDOW_AUTOSIZE ); + cvShowImage( "out", src ); + cvNamedWindow( "template", CV_WINDOW_AUTOSIZE ); + cvShowImage( "template", templ ); + + // On attend 10 ms + key = cvWaitKey(1000); + + // On essaye de capturer la frame suivante + // if(!cvGrabFrame( int centre_y=(int)((max_loc.y-max_loc2.y)/2);capture )) key = 27; + + } +while(1); + // On détruit les fenêtres créées + cvDestroyAllWindows(); + + // On détruit la capture + // cvReleaseCapture( &capture ); + + return 0; + +} + diff --git a/omap3/traitementImages/code_sara/makefile b/omap3/traitementImages/code_sara/makefile new file mode 100644 index 0000000000000000000000000000000000000000..9ea2d0c17605bb6739418c3782c7c98316a416e3 --- /dev/null +++ b/omap3/traitementImages/code_sara/makefile @@ -0,0 +1,17 @@ +C=g++ +CFLAGS=-c -Wall -g -O0 `pkg-config opencv --cflags` +LDFLAGS=`pkg-config opencv --libs` +SOURCES=applatir.cpp +OBJECTS=$(SOURCES:.cpp=.o) +EXECUTABLE=applatir.bin + +all: $(SOURCES) $(EXECUTABLE) + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +.cpp.o: + $(CC) $(CFLAGS) $< -o $@ + +clean: + rm *.o diff --git a/omap3/traitementImages/code_sara2/applatir.cpp b/omap3/traitementImages/code_sara2/applatir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c8f21a105a9b812ea05095f10c1993d90197e3b --- /dev/null +++ b/omap3/traitementImages/code_sara2/applatir.cpp @@ -0,0 +1,133 @@ +//Matching avec cvMatchTemplate() +#include +#include +#include + +#include "cv.h" +#include "cxcore.h" +#include "highgui.h" +#include "iostream" +using namespace std; + +/*enregistrez une image template en appuyant sur 'espace' +cette image sera recherchée dans la video issue de la webcam +matchtemplate retourne une valeur de corrélation pour chaque pixel de l'image +la valeur la plus grande de corrélation correspond très probablement au template recherché +pour un matching plus précis, il est possible de régler le seuil à partir duquel il y a matching +pour cela, observer dans la console la valeur maximale de corrélation pour chaque frame +puis agir sur la trackbar de seuil*/ + +int main() { + + //définition des images a utiliser + IplImage *src,*hsv,*mask;//=cvCreateImage(cvSize(640,480), 8, 3); + IplImage *templ;// = cvCreateImage(cvSize(200,300), 8, 3); + + templ = cvLoadImage("motif.JPG"); + if(!templ) + { + printf("Erreur \n"); + return -1; + + } +src = cvLoadImage("image.JPG"); +if(!src) + { + printf("Erreur \n"); + return -1; + + } + + + + //définition de la taille(largeur, hauteur) de l'image ftmp + int iwidth = src->width - templ->width + 1; + int iheight = src->height - templ->height + 1; + IplImage *ftmp = cvCreateImage(cvSize(iwidth,iheight),IPL_DEPTH_32F,1); + + //seuil qui pourra être réglé avec un trackbar pour une détection plus pertinente + double seuil = 80.0; + //le trackbar n'acceptant que des valeurs entières on utilise 'seuil_int' + int seuil_int = (int) seuil; +//int center_x=0,center_y=0; +CvPoint min_loc_ant, max_loc_ant; +min_loc_ant.x=min_loc_ant.y=max_loc_ant.x=max_loc_ant.y=0; +CvPoint min_loc, max_loc; +min_loc_ant.x=min_loc_ant.y=max_loc_ant.x=max_loc_ant.y=2; + + +max_loc_ant.x=-1; +max_loc_ant.y=-1; +min_loc_ant.x=-1; +min_loc_ant.y=-1; +int key=1; + + cvSmooth(src,src,CV_MEDIAN,3); +int repite=0,premiermotiftrouve=0; + + while (repite==0) + { + + + cvMatchTemplate( src, templ, ftmp, CV_TM_CCOEFF_NORMED);//trouver ce qui correspond à 'templ' dans 'src' + //src: l'image source capturée par la caméra + //templ: le template qui sera recherché dans l'image source + //ftmp: l'image qui contient le réultat du calcul + //CV_TM_CCOEFF_NORMED: la méthode de calcul utilisée ici permet un matching plus pertinent mais au prix de plus de calcul + + + //retrouver dans 'ftmp' les coordonnées du point ayant une valeur maximale + double min_val, max_val; + + cvMinMaxLoc(ftmp, &min_val, &max_val, &min_loc, &max_loc); + + //défnir un deuxième point à partir du premier point et de la taille de 'ftmp' + CvPoint max_loc2 = cvPoint(max_loc.x + templ->width, max_loc.y + templ->height);//définir le deuxième point en fonction de la taille du template + + //trackelfbar pour régler le seuil + cvCreateTrackbar( "seuil", "out", &seuil_int, 100, NULL ); + + // 'seuil' appartient à [0 1] alors que 'seuil_int' appartient à [0 100] donc: + seuil = (double) seuil_int / 100.0; + + + + //si la valeur maximale de 'ftmp' est supérieure au 'seuil' + //dessiner un rectangle rouge utilisant les coordonnées des deux points 'max_loc' et 'max_loc2' + if( max_val > seuil && max_val!=1 ) + { + if(premiermotiftrouve==0) + { + max_loc_ant.x=max_loc.x; + max_loc_ant.y=max_loc.y; + min_loc_ant.x=min_loc.x; + min_loc_ant.y=min_loc.y; + premiermotiftrouve=1; + } + else if((max_loc.x==max_loc_ant.x) && (max_loc.y==max_loc_ant.y) && (min_loc.x==min_loc_ant.x) && (min_loc.x==min_loc_ant.x)) + { + repite=1; + } + cvRectangle(src, max_loc,max_loc2, cvScalar(0,0,255)); + printf("\nx1=%d x2_x=%d y1=%d y2=%d",max_loc.x,max_loc2.x,max_loc.y,max_loc2.y); + + + } + + + cvNamedWindow( "out", CV_WINDOW_AUTOSIZE ); + cvShowImage( "out", src ); + cvNamedWindow( "template", CV_WINDOW_AUTOSIZE ); + cvShowImage( "template", templ ); + + // On attend 10 ms + key = cvWaitKey(1000); + } +while(1); + // On détruit les fenêtres créées + cvDestroyAllWindows(); + + return 0; + +} +