CamAdventure
 All Files Functions Macros
Navy.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <cv.h>
4 #include <highgui.h>
5 //#include <opencv2/highgui.hpp> //Pour le cvRound
6 //#include "opencv2/videoio/videoio_c.h" //Pour le CvCapture*
7 
8 //#include <cxcore.h>
9 //#include <SFML/Window.h>
10 #include <SFML/Audio.hpp>
11 #include <SFML/Graphics.hpp>
12 #include <SFML/Window.hpp>
13 #include <SFML/System.hpp> //inutilisé pour le moment
14 
15 //#define CONFIG
16 #define SFML
17 
18 #define KIRBY
19 //#define ETOILE
20 
21 #define JEU 0.15
22 
23 //ATTENTION AFFICHAGE OPENCV INCOMPATIBLE AVEC AFFICHAGE SFML
24 //ATTENTION SFML SUPPORTE UN NOMBRE LIMITE DE SPRITE EN FCT DU PC
25 
26 /*Headers*/
27 void maj_angle(int vecX, int vecY, int rayon, double* angle); //Met à jour l'angle selon la distance CentreCamera - Cible
28 int ajust_pos(int pos, int ref);
29 void controle_moteur(double* angle);//Envoie les angles au moteur
30 int limite_moteur(int val_pwm);//Verifie que les valeurs envoyees aux moteurs sont correctes
31 
32 void config(int* LowH, int* HighH, int* LowS, int* HighS, int* LowV, int* HighV); //Affiche le panneau de configuration de tracking avec les arguments comme valeur de base
33 void affichage_config(IplImage* frame, IplImage* HSV, IplImage* Binaire); //Affiche le flux vidéos et ses différent traitements
34 void Affichage_Tracking(IplImage* frame, int posX, int posY, int width, int height); //Dessine les informations de tracking sur frame
35 
36 void Position_moy(IplImage* Binaire, int* posX, int * posY); //Effectue le baricentre des pixels d'une image binaire pour obtenir la postion de l'objet
37 void traitement(IplImage* frame, IplImage* HSV, IplImage* Binaire, int LowH, int HighH, int LowS, int HighS, int LowV, int HighV); //Effectue une binarisation de frame en fonction des bornes HSV
38 
39 int image_CV2SFML(IplImage* imcv, sf::Image imFlux); //Construction de imsf (RGBA) à partir de imcv (BGR), avec alpha constant (=1)
40 
41 
42 int main(int argc, char* argv[])
43 {
44  //Initialisations
45  int height,width; //parameters of the image we are working on
46  int posX, posY; //Position objet
47  int boucle;
48 
49  double angle[2] = {100,100};
50 
51  int tracking;
52 
53 
54 #ifdef SFML
55  //Initialisation SFML
56 
57  sf::Texture txFlux;
58  sf::Sprite spFlux;
59  sf::Image imFlux;
60  sf::Event event;
61 
62  tracking = 0; //Pas de tracking de base en mode SFML
63 
64 #endif
65 
66  //Ouverture flux camera
67  CvCapture* capture = cvCaptureFromCAM( 0 );
68 
69  if( !capture ){
70  printf("ERROR: capture is NULL \n" );
71  exit(EXIT_FAILURE);
72  }
73 
74 
75  // grab an image from the capture
76  IplImage* frame = cvQueryFrame( capture );
77 
78  // get the image data
79  height = frame->height;
80  width = frame->width;
81 
82  // capture size -
83  CvSize size = cvSize(width,height);
84 
85 
86 #ifdef SFML
87  //Création de la fenetre principale
88  sf::RenderWindow window(sf::VideoMode(width+300, height), "KirbyTrack");
89 #endif
90 
91  // Initialize different images that are going to be used in the program
92  IplImage* hsv_frame = cvCreateImage(size, IPL_DEPTH_8U, 3); // image converted to HSV plane
93  IplImage* threshold = cvCreateImage(size, IPL_DEPTH_8U, 1);
94 
95 
96  //Controle couleur
97 #ifdef KIRBY
98  //Setup Kirby
99  int iLowH = 152;
100  int iHighH = 179;
101 
102  int iLowS = 48;
103  int iHighS = 255;
104 
105  int iLowV = 101;
106  int iHighV = 255;
107 #endif
108 #ifdef ETOILE
109  //Setup Etoile
110  int iLowH = 20;
111  int iHighH = 30;
112 
113  int iLowS = 100;
114  int iHighS = 255;
115 
116  int iLowV = 100;
117  int iHighV = 255;
118 #endif
119 
120 #ifdef CONFIG
121  //Affichage du panneau de config
122  config(&iLowH, &iHighH, &iLowS, &iHighS, &iLowV, &iHighV);
123 
124  boucle = 1;
125  tracking = 1; //Tracking de base en mode CONFIG
126 #endif
127 
128  while(boucle)
129  {
130 
131 #ifdef SFML
132  boucle = window.isOpen();
133 
134  // on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
135  while (window.pollEvent(event))
136  {
137  // évènement "fermeture demandée" : on ferme la fenêtre
138  if (event.type == sf::Event::Closed)
139  window.close();
140  }
141 #endif
142 
143  // Get one frame
144  frame = cvQueryFrame( capture );
145 
146  if( !frame ){
147  perror("ERROR: frame is null...");
148  break;
149  }
150 
151  //Binarisation du flux vidéo
152  traitement(frame, hsv_frame, threshold, iLowH, iHighH, iLowS, iHighS, iLowV, iHighV);
153 
154  // Calculate the moments to estimate the position of the ball
155  Position_moy(threshold, &posX, &posY);
156 
157  //Dessine les informations de tracking sur frame
158  Affichage_Tracking(frame, posX, posY, width, height);
159 
160 
161 #ifdef SFML
162  //Affichage SFML
163  /* Clear the screen */
164  window.clear(sf::Color::White);
165 
166  //Conversion de la frame en image smfl
167  /*if(image_CV2SFML(frame, imFlux)){
168  printf("Erreur conversion OpenCV-SFML\n");
169  break;
170  }
171  */
172 
173  //Enregistrement de la frame openCV
174  cvSaveImage("Stock SFML/temp.jpg", frame);
175 
176  //Chargement de la frame en texture SFML
177  if (!txFlux.loadFromFile("Stock SFML/temp.jpg")){
178  printf("Erreur chargement image SFML\n" );
179  break;
180  }
181 
182  spFlux.setTexture(txFlux);
183 
184  window.draw(spFlux);
185 
186 //TEST SFML
187  sf::Vector2i PosMouse = sf::Mouse::getPosition(window);
188  //Detection du bouton tracking
189  if (sf::Mouse::isButtonPressed(sf::Mouse::Left)&&(PosMouse.x>640)&&(PosMouse.x<760)&&(PosMouse.y>0)&&(PosMouse.y<120)){
190  //printf("\n\n\n OK \n\n\n");
191  if (tracking){ tracking = 0;}
192  else tracking = 1;
193  cvWaitKey(100);
194  }
195  //printf("Pos Mouse : %d %d \n", PosMouse.x, PosMouse.y);
196 
197  //Dessin du bouton de tracking
198  sf::Texture txBut;
199  sf::Sprite button_tracking;
200 
201  if (!txBut.loadFromFile("Stock SFML/button.png")){
202  printf("Erreur chargement image SFML\n" );
203  break;
204  }
205 
206  button_tracking.setTexture(txBut);
207  button_tracking.setScale(0.5,0.5);
208  button_tracking.setPosition(sf::Vector2f(width+20, 20));
209 
210  if(tracking){ button_tracking.setColor(sf::Color::Green); }
211  else{ button_tracking.setColor(sf::Color::Red); }
212 
213  window.draw(button_tracking);
214 
215  //Dessin du bouton reset
216  sf::Texture txBut2;
217  sf::Sprite button_reset;
218 
219  if (!txBut2.loadFromFile("Stock SFML/button.png")){
220  printf("Erreur chargement image SFML\n" );
221  break;
222  }
223 
224  button_reset.setTexture(txBut2);
225  button_reset.setScale(0.5,0.5);
226  button_reset.setPosition(sf::Vector2f(width+20, 100));
227 
228  window.draw(button_reset);
229 
230 /*
231  //Ajout du texte
232  sf::Font font;
233  if (!font.loadFromFile("Stock SFML/arial.ttf")){
234  printf("Erreur chargement police SFML\n" );
235  break;
236  }
237 
238  sf::Text text;
239  // choix de la police à utiliser
240  text.setFont(font); // font est un sf::Font
241 
242  // choix de la chaîne de caractères à afficher
243  text.setString("Tracking Moteur");
244 
245  // choix de la taille des caractères
246  text.setCharacterSize(24); // exprimée en pixels, pas en points !
247 
248  //text.setFillColor(sf::Color::Black);
249  text.setColor(sf::Color::Black);
250 
251  text.setPosition(sf::Vector2f(width+100, 35));
252 
253  window.draw(text);
254 */
255 /*
256  //Link
257  sf::Texture txLink;
258  sf::Sprite Link;
259 
260  if (!txLink.loadFromFile("Stock SFML/link.png")){
261  printf("Erreur chargement image SFML\n" );
262  break;
263  }
264 
265  Link.setTexture(txLink);
266  Link.setPosition(sf::Vector2f(posX-75, posY-75));
267 
268  window.draw(Link);
269 */
270  /* Update the window */
271  window.display();
272 
273 #endif
274 
275  if(tracking){
276  //Mouvements moteurs
277  //printf("-PREMAJ_ANGLE...: %d %d\n",width,height);
278 
279  maj_angle(ajust_pos(posX-width/2,width), ajust_pos(posY-height/2,height), height*JEU, angle);
280  controle_moteur(angle);
281 
282  cvWaitKey(50);
283  }
284 
285 
286 #ifdef CONFIG
287  affichage_config(frame, hsv_frame, threshold); //Affichage du flux vidéo et de ses traitements
288 
289  if( (cvWaitKey(10) ) >= 0 ) break; //Arret capture
290 #endif
291 
292  }
293 
294  //cvWaitKey(0); //Fin programme
295 
296  // Release the capture device housekeeping
297  cvReleaseCapture( &capture );
298 
299  cvReleaseImage(&threshold);
300  cvReleaseImage(&hsv_frame);
301  cvReleaseImage(&frame);
302 
303  return EXIT_SUCCESS;
304 }
305 
306 
307 void maj_angle(int vecX, int vecY, int rayon, double* angle){
308  //On ajustera coeff fonction du rayon. Si la cible est à une distance 5*r, il sera 5x plus rapide que s'il était à 1*r
309 
310  double coeffx, coeffy;
311  int l0, l1;
312 
313  //printf("-MAJ_ANGLE...Valeur maj_angle arguments : %d %d %d\n\tAnciens angles : %d %d\n\t",vecX,vecY,rayon,(int)angle[0],(int)angle[1]);
314 
315 
316  //Ajout d'un angle moteur pondéré par la distance
317  coeffx = -0.2*vecX/rayon;
318  coeffy = 0.2*vecY/rayon;
319  angle[0] += coeffx;
320  angle[1] += coeffy;
321 
322  //Majoration - minoration des angles moteurs
323  l0 = limite_moteur(angle[0]);
324  l1 = limite_moteur(angle[1]);
325  if (l0 != 0) angle[0] = l0;
326  if (l1 != 0) angle[1] = l1;
327 
328  //printf("Nouveaux angles : %lf %lf %d %d\n",angle[0],angle[1],(int)angle[0],(int)angle[0]);
329 }
330 
331 int ajust_pos(int pos, int ref){
332  if (pos > ref) return 0;
333  else return pos;
334 }
335 
336 int limite_moteur(int val_pwm){
337  int MAX_PWM = 130, MIN_PWM = 30;
338  if (val_pwm > MAX_PWM){
339  return MAX_PWM;
340  }
341  else if (val_pwm < MIN_PWM){
342  return MIN_PWM;
343  }
344  else{
345  return 0;
346  }
347 }
348 
349 void controle_moteur(double* angle){
350 
351  //Ouverture port serie
352  FILE* fichier = NULL;
353  fichier = fopen("/dev/ttyACM0","w");
354  if(fichier==NULL){
355  printf("Erreur ouverture fichier\n");
356  perror("fopen failed for /dev/ttyACM0" );
357  exit( EXIT_FAILURE );
358  }
359 
360  //Ecriture angles
361  fprintf(fichier,"%d\n",(int)angle[0]);
362  fprintf(fichier,"%d\n",(int)angle[1]);
363 
364  //Fermeture
365  fclose(fichier);
366  return;
367 }
368 
369 int image_CV2SFML(IplImage* imcv, sf::Image imFlux){
370 
371  int R, G, B;
372  int w = imcv->widthStep;
373  char* ptr = imcv->imageData;
374 
375  imFlux.create(imcv->width,imcv->height, NULL); //Initialise une image vide
376 
377  for( int y=0; y<imcv->height; y++ ) {
378  //uchar* ptr = (uchar*) ( imcv->imageData + y * imcv->widthStep );
379  for( int x=0; x<imcv->width; x++ ) {
380  //Recupération du pixel
381  B = ptr[y*w + 3*x];
382  G = ptr[y*w + 3*x + 1];
383  R = ptr[y*w + 3*x + 2];
384 
385  //Ecriture du pixel associé
386  imFlux.setPixel(x,y,sf::Color(R,G,B,1)); //Alpha channel = 1
387  }
388  }
389 
390  return 0;
391 }
392 
393 
394 void traitement(IplImage* frame, IplImage* HSV, IplImage* Binaire, int LowH, int HighH, int LowS, int HighS, int LowV, int HighV){ //Effectue une binarisation de frame en fonction des bornes HSV
395 
396  // Covert color space to HSV as it is much easier to filter colors in the HSV color-space.
397  cvCvtColor(frame, HSV, CV_BGR2HSV);
398 
399  //Blur
400  cvSmooth( HSV, HSV, CV_GAUSSIAN, 15, 0,0,0); //suppression des parasites par flou gaussien
401 
402  //Binarisation
403 
404  CvScalar valinf={(double)LowH,(double)LowS,(double)LowV};
405  CvScalar valsup={(double)HighH,(double)HighS,(double)HighV};
406 
407  cvInRangeS(HSV, valinf,valsup, Binaire);
408 
409  //En cas d'erreur sur les trois ligne précédentes
410  //cvInRangeS(HSV, CvScalar(LowH,LowS,LowV),CvScalar(HighH,HighS,HighV), Binaire);
411 
412  //cvSmooth( Binaire, Binaire, CV_GAUSSIAN, 9, 9 ); //Legère suppression des parasites
413 }
414 
415 void Position_moy(IplImage* Binaire, int* posX, int * posY){ //Effectue le baricentre des pixels d'une image binaire pour obtenir la postion de l'objet
416 
417  CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
418 
419  cvMoments(Binaire, moments, 1);
420  // The actual moment values
421  double moment10 = cvGetSpatialMoment(moments, 1, 0);
422  double moment01 = cvGetSpatialMoment(moments, 0, 1);
423  double area = cvGetCentralMoment(moments, 0, 0);
424 
425  *posX = moment10/area;
426  *posY = moment01/area;
427 
428  free(moments);
429 }
430 
431 void config(int* LowH, int* HighH, int* LowS, int* HighS, int* LowV, int* HighV){ //Affiche le panneau de configuration de tracking avec les arguments comme valeur de base
432 
433  cvNamedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"
434 
435  //Create trackbars in "Control" window
436  cvCreateTrackbar("LowH", "Control", LowH, 179,NULL); //Hue (0 - 179)
437  cvCreateTrackbar("HighH", "Control", HighH, 179,NULL);
438 
439  cvCreateTrackbar("LowS", "Control", LowS, 255,NULL); //Saturation (0 - 255)
440  cvCreateTrackbar("HighS", "Control", HighS, 255,NULL);
441 
442  cvCreateTrackbar("LowV", "Control", LowV, 255,NULL); //Value (0 - 255)
443  cvCreateTrackbar("HighV", "Control", HighV, 255,NULL);
444 }
445 
446 void affichage_config(IplImage* frame, IplImage* HSV, IplImage* Binaire){ //Affiche le flux vidéos et ses différent traitements
447 
448  // Create a window in which the captured images will be presented
449  cvNamedWindow( "HSV", CV_WINDOW_AUTOSIZE );
450  cvNamedWindow( "Binaire", CV_WINDOW_AUTOSIZE );
451  cvNamedWindow( "Camera", CV_WINDOW_AUTOSIZE );
452 
453  cvShowImage( "HSV", HSV); // Original stream in the HSV color space
454  cvShowImage( "Binaire", Binaire); // The stream after color filtering
455  cvShowImage( "Camera", frame ); // Flux caméra avec tracking objet
456 }
457 
458 void Affichage_Tracking(IplImage* frame, int posX, int posY, int width, int height){ //Dessine les informations de tracking sur frame
459 
460  //Affichage zone suivie objet
461  cvCircle(frame, cvPoint(width/2,height/2), height*JEU, CV_RGB(0, 255, 0), 4, 8, 0 );
462 
463  if(posX<5&&posY<5){ //Si aucun objet spotted, pointeur rouge au centre
464  posX=width/2;
465  posY=height/2;
466  cvLine(frame, cvPoint(posX-20,posY), cvPoint(posX+20,posY), CV_RGB(255, 0, 0), 4, 8, 0 );
467  cvLine(frame, cvPoint(posX,posY-20), cvPoint(posX,posY+20), CV_RGB(255, 0, 0), 4, 8, 0 );
468  }
469  else{ //Objet spotted
470  //Affichage position de l'objet
471  cvLine(frame, cvPoint(posX-20,posY), cvPoint(posX+20,posY), CV_RGB(0, 0, 255), 4, 8, 0 );
472  cvLine(frame, cvPoint(posX,posY-20), cvPoint(posX,posY+20), CV_RGB(0, 0, 255), 4, 8, 0 );
473  }
474 }
void Position_moy(IplImage *Binaire, int *posX, int *posY)
Effectue le baricentre des pixels d'une image binaire pour obtenir la postion de l'objet.
Definition: KirbyTrack.c:474
void config(int *LowH, int *HighH, int *LowS, int *HighS, int *LowV, int *HighV)
Fonction d'affichage du panneau de configuration de la couleur à suivre.
Definition: KirbyTrack.c:490
#define JEU
Coefficient de tolérance pour le suivi d'objet.
Definition: KirbyTrack.c:42
int ajust_pos(int pos, int ref)
permet d'éviter des positions supérieures à ref considérées comme aberrantes.
Definition: KirbyTrack.c:415
void maj_angle(int vecX, int vecY, int rayon, double *angle)
Met à jour angle selon la distance entre le centre de la caméra et la cible, avec un tolérance circul...
Definition: KirbyTrack.c:391
int limite_moteur(int val_pwm)
Fonction qui vérifie que les valeurs envoyees aux moteurs sont correctes.
Definition: KirbyTrack.c:420
void Affichage_Tracking(IplImage *frame, int posX, int posY, int width, int height)
Fonction d'affichage des informations de suivi.
Definition: KirbyTrack.c:517
int main(int argc, char *argv[])
Entrée du programme.
Definition: KirbyTrack.c:162
void controle_moteur(double *angle)
Fonction d'envoie des angles aux moteurs.
Definition: KirbyTrack.c:433
void affichage_config(IplImage *frame, IplImage *HSV, IplImage *Binaire)
Fonction d'affichage du flux vidéo, du flux en HSV et de sa binarisation.
Definition: KirbyTrack.c:505
void traitement(IplImage *frame, IplImage *HSV, IplImage *Binaire, int LowH, int HighH, int LowS, int HighS, int LowV, int HighV)
Effectue une binarisation de frame en fonction des bornes HSV.
Definition: KirbyTrack.c:453