No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

image.cpp 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /**
  2. * \file image.cpp
  3. * \author L.Senaneuch
  4. * \version 1.0
  5. * \date 06/06/2017
  6. * \brief Fonctions de traitement d'image utilisable pour la détection du robot.
  7. *
  8. * \details Ce fichier utilise la libraire openCV2 pour faciliter le traitement d'image dans le projet Destijl.
  9. * Il permet de faciliter la détection de l'arène et la détection du robot.
  10. * /!\ Attention Bien que celui-ci soit un .cpp la structure du code n'est pas sous forme d'objet.
  11. */
  12. #include "image.h"
  13. #include <iostream>
  14. using namespace cv;
  15. #ifndef __STUB__
  16. using namespace raspicam;
  17. #else
  18. Image stubImg;
  19. #endif
  20. using namespace std;
  21. float calculAngle(Position * positionRobot);
  22. int cropArena(Image *imgInput, Image *imgOutput, Arene *AreneInput);
  23. float euclideanDist(Point& p, Point& q);
  24. void draw_arena(Image *imgInput, Image *imgOutput, Arene *monArene)
  25. {
  26. if(imgInput!=imgOutput)
  27. *imgOutput=imgInput->clone();
  28. rectangle(*imgOutput,monArene->tl(),monArene->br(),Scalar(0,0,125),2,8,0);
  29. }
  30. int open_camera(Camera *camera)
  31. {
  32. #ifndef __STUB__
  33. camera->set(CV_CAP_PROP_FORMAT, CV_8UC3);
  34. camera->set(CV_CAP_PROP_FRAME_WIDTH,WIDTH);
  35. camera->set(CV_CAP_PROP_FRAME_HEIGHT,HEIGHT);
  36. printf("Opening Camera...\n");
  37. if (!(camera->open())) {
  38. perror("Can't open Camera\n") ;
  39. return -1;
  40. }
  41. else
  42. {
  43. printf("Camera warmup 2sec\n");
  44. sleep(2);
  45. printf("Start capture\n");
  46. return 0;
  47. }
  48. #endif
  49. }
  50. void get_image(Camera *camera, Image * monImage, const char * fichier) // getImg(Camera, Image img);
  51. {
  52. #ifndef __STUB__
  53. camera->grab();
  54. camera->retrieve(*monImage);
  55. cvtColor(*monImage,*monImage,CV_BGR2RGB);
  56. #else
  57. stubImg = imread(fichier, CV_LOAD_IMAGE_COLOR);
  58. stubImg.copyTo(*monImage);
  59. #endif
  60. }
  61. void close_camera(Camera *camera) // closeCam(Camera) : camera Entrer
  62. {
  63. #ifndef __STUB__
  64. camera->release();
  65. #endif
  66. }
  67. int detect_arena(Image *monImage, Arene *rectangle) // Image en entrée // rectangle en sortie
  68. {
  69. vector<vector<Point> > contours;
  70. vector<Point> approx;
  71. vector<Vec4i> hierarchy;
  72. Image imageTrt;
  73. cvtColor(*monImage,imageTrt,CV_RGB2GRAY); // conversion en niveau de gris
  74. threshold(imageTrt,imageTrt,128,255,CV_THRESH_BINARY); // Threshold les éléments les plus clair
  75. Canny(imageTrt, imageTrt, 100,200,3); // detection d'angle
  76. findContours(imageTrt, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
  77. for(unsigned int i = 0; i < contours.size();i++)
  78. {
  79. approxPolyDP(Image(contours[i]), approx, arcLength(Image(contours[i]), true)*0.1, true);
  80. if(approx.size()==4 && fabs(cv::contourArea(contours[i])) > 100000)
  81. {
  82. *rectangle = boundingRect(Image(contours[i]));
  83. return 0;
  84. }
  85. }
  86. return -1;
  87. }
  88. int cropArena(Image *imgInput, Image *imgOutput, Arene *areneInput) // image // rectangle // image2
  89. {
  90. Image img;
  91. img=imgInput->clone();
  92. *imgOutput = img(*areneInput);
  93. return 0;
  94. }
  95. float euclideanDist(Point& p, Point& q) {
  96. Point diff = p - q;
  97. return cv::sqrt(diff.x*diff.x + diff.y*diff.y);
  98. }
  99. void compress_image(Image *imgInput, Jpg *imageCompress) // image entrée // imageEncodé en sortie
  100. {
  101. imencode(".jpg",*imgInput,*imageCompress);
  102. }
  103. int detect_position(Image *imgInput, Position *posTriangle, Arene * monArene) // entree : image / sortie tab pos
  104. {
  105. vector<vector<Point> > contours;
  106. vector<Point> approx;
  107. vector<Vec4i> hierarchy;
  108. Image imgTraitment;
  109. if(monArene==NULL)
  110. imgTraitment=imgInput->clone();
  111. else
  112. cropArena(imgInput,&imgTraitment, monArene);
  113. cvtColor(imgTraitment,imgTraitment,CV_RGB2GRAY);
  114. threshold(imgTraitment,imgTraitment,128,255,CV_THRESH_BINARY);
  115. findContours(imgTraitment, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
  116. int nbrTriangle = 0;
  117. for(unsigned int i = 0;i < contours.size();i++)
  118. {
  119. approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.17, true);
  120. if(approx.size() == 3 && fabs(contourArea(contours[i])) > 200 && fabs(contourArea(contours[i])) < 700)
  121. {
  122. Point a,b,c;
  123. Point center;
  124. a = approx[0];
  125. b = approx[1];
  126. c = approx[2];
  127. if(monArene !=NULL) // ajout de l'offset de l'arène
  128. {
  129. a.x += monArene->x;
  130. a.y += monArene->y;
  131. b.x += monArene->x;
  132. b.y += monArene->y;
  133. c.x += monArene->x;
  134. c.y += monArene->y;
  135. }
  136. center.x = (a.x + b.x + c.x)/3;
  137. center.y = (a.y + b.y + c.y)/3;
  138. posTriangle[nbrTriangle].center=center;
  139. if(euclideanDist(center,b) > euclideanDist(center,a) && euclideanDist(center,b) > euclideanDist(center,c) )
  140. {
  141. posTriangle[nbrTriangle].direction=b;
  142. //line(img,center,b,Scalar(0,125,0),2,8,0);
  143. }
  144. else if(euclideanDist(center,a) > euclideanDist(center,c))
  145. {
  146. posTriangle[nbrTriangle].direction=a;
  147. //line(img,center,a,Scalar(0,125,0),2,8,0);
  148. }
  149. else
  150. {
  151. posTriangle[nbrTriangle].direction=c;
  152. //line(img,center,c,Scalar(0,125,0),2,8,0);
  153. }
  154. posTriangle[nbrTriangle].angle=calculAngle(&posTriangle[nbrTriangle]);
  155. nbrTriangle++;
  156. }
  157. }
  158. return nbrTriangle;
  159. }
  160. void draw_position(Image *imgInput, Image *imgOutput, Position *positionRobot) // img E/S pos : E
  161. {
  162. if(imgInput!=imgOutput)
  163. {
  164. *imgOutput=imgInput->clone();
  165. }
  166. line(*imgOutput,positionRobot->center,positionRobot->direction,Scalar(0,125,0),2,8,0);
  167. }
  168. float calculAngle(Position * positionRobot) // position en entree
  169. {
  170. float a = positionRobot->direction.x - positionRobot->center.x;
  171. float b = positionRobot->direction.y - positionRobot->center.y ;
  172. float angle = atan2(b,a);
  173. return angle * 180.f/M_PI;
  174. }