Bibliotheques TP RT  1.0
Bibliotheque de support pour TP/RT
image.cpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) 2018 dimercur
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
31 #include "image.h"
32 #include <iostream>
33 
34 using namespace cv;
35 #ifndef __STUB__
36 #ifdef __FOR_PC__
37 VideoCapture cap;
38 #else
39 using namespace raspicam;
40 #endif /* __FOR_PC__ */
41 #else
42 Image stubImg;
43 
44 #endif
45 using namespace std;
46 
47 float calculAngle(Position * positionRobot);
48 int cropArena(Image *imgInput, Image *imgOutput, Arene *AreneInput);
49 float euclideanDist(Point& p, Point& q);
50 
51 void draw_arena(Image *imgInput, Image *imgOutput, Arene *monArene)
52 {
53  if(imgInput!=imgOutput)
54  *imgOutput=imgInput->clone();
55  rectangle(*imgOutput,monArene->tl(),monArene->br(),Scalar(0,0,125),2,8,0);
56 }
57 
58 int open_camera(Camera *camera)
59 {
60 #ifndef __STUB__
61 #ifdef __FOR_PC__
62  // open the default camera, use something different from 0 otherwise;
63  // Check VideoCapture documentation.
64  printf("Opening Camera...\n");
65  if(!cap.open(0))
66  return -1;
67 
68  return 0;
69 #else // for raspberry
70 
71  camera->set(CV_CAP_PROP_FORMAT, CV_8UC3);
72  camera->set(CV_CAP_PROP_FRAME_WIDTH,WIDTH);
73  camera->set(CV_CAP_PROP_FRAME_HEIGHT,HEIGHT);
74 
75  printf("Opening Camera...\n");
76  if (!(camera->open())) {
77  perror("Can't open Camera\n") ;
78  return -1;
79  }
80  else
81  {
82  printf("Camera warmup 2sec\n");
83  sleep(2);
84  printf("Start capture\n");
85  return 0;
86  }
87 #endif /* __FOR_PC__ */
88 #else
89  return 0;
90 #endif
91 }
92 
93 void get_image(Camera *camera, Image * monImage, const char * fichier) // getImg(Camera, Image img);
94 {
95 #ifndef __STUB__
96 #ifdef __FOR_PC__
97  if (monImage != NULL)
98  {
99  cap>>*monImage;
100  }
101 #else // for raspberry
102  camera->grab();
103  camera->retrieve(*monImage);
104  cvtColor(*monImage,*monImage,CV_BGR2RGB);
105 #endif /* __FOR_PC__ */
106 #else
107  stubImg = imread(fichier, CV_LOAD_IMAGE_COLOR);
108  stubImg.copyTo(*monImage);
109 #endif
110 }
111 
112 void close_camera(Camera *camera) // closeCam(Camera) : camera Entrer
113 {
114 #ifndef __STUB__
115 #ifdef __FOR_PC__
116  cap.release();
117 #else // for raspberry
118  camera->release();
119 #endif /* __FOR_PC__ */
120 #else
121 
122 #endif
123 }
124 
125 
126 int detect_arena(Image *monImage, Arene *rectangle) // Image en entrée // rectangle en sortie
127 {
128  vector<vector<Point> > contours;
129  vector<Point> approx;
130  vector<Vec4i> hierarchy;
131 
132  Image imageTrt;
133  cvtColor(*monImage,imageTrt,CV_RGB2GRAY); // conversion en niveau de gris
134  threshold(imageTrt,imageTrt,128,255,CV_THRESH_BINARY); // Threshold les éléments les plus clair
135  Canny(imageTrt, imageTrt, 100,200,3); // detection d'angle
136 
137  findContours(imageTrt, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
138  for(unsigned int i = 0; i < contours.size();i++)
139  {
140  approxPolyDP(Image(contours[i]), approx, arcLength(Image(contours[i]), true)*0.1, true);
141  if(approx.size()==4 && fabs(cv::contourArea(contours[i])) > 100000)
142  {
143  *rectangle = boundingRect(Image(contours[i]));
144  return 0;
145  }
146  }
147  return -1;
148 }
149 
150 int cropArena(Image *imgInput, Image *imgOutput, Arene *areneInput) // image // rectangle // image2
151 {
152  Image img;
153  img=imgInput->clone();
154 
155  *imgOutput = img(*areneInput);
156  return 0;
157 }
158 
159 float euclideanDist(Point& p, Point& q) {
160  Point diff = p - q;
161  return cv::sqrt(diff.x*diff.x + diff.y*diff.y);
162 }
163 
164 void compress_image(Image *imgInput, Jpg *imageCompress) // image entrée // imageEncodé en sortie
165 {
166  imencode(".jpg",*imgInput,*imageCompress);
167 }
168 
169 
170 int detect_position(Image *imgInput, Position *posTriangle, Arene * monArene) // entree : image / sortie tab pos
171 {
172  vector<vector<Point> > contours;
173  vector<Point> approx;
174  vector<Vec4i> hierarchy;
175 
176  Image imgTraitment;
177 
178  if(monArene==NULL)
179  imgTraitment=imgInput->clone();
180  else
181  cropArena(imgInput,&imgTraitment, monArene);
182 
183  cvtColor(imgTraitment,imgTraitment,CV_RGB2GRAY);
184  threshold(imgTraitment,imgTraitment,128,255,CV_THRESH_BINARY);
185  findContours(imgTraitment, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
186 
187  int nbrTriangle = 0;
188  for(unsigned int i = 0;i < contours.size();i++)
189  {
190  approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.17, true);
191  if(approx.size() == 3 && fabs(contourArea(contours[i])) > 200 && fabs(contourArea(contours[i])) < 700)
192  {
193 
194  Point a,b,c;
195  Point center;
196 
197 
198  a = approx[0];
199  b = approx[1];
200  c = approx[2];
201 
202 
203  if(monArene !=NULL) // ajout de l'offset de l'arène
204  {
205  a.x += monArene->x;
206  a.y += monArene->y;
207  b.x += monArene->x;
208  b.y += monArene->y;
209  c.x += monArene->x;
210  c.y += monArene->y;
211  }
212 
213  center.x = (a.x + b.x + c.x)/3;
214  center.y = (a.y + b.y + c.y)/3;
215 
216  posTriangle[nbrTriangle].center=center;
217 
218  if(euclideanDist(center,b) > euclideanDist(center,a) && euclideanDist(center,b) > euclideanDist(center,c) )
219  {
220 
221  posTriangle[nbrTriangle].direction=b;
222  //line(img,center,b,Scalar(0,125,0),2,8,0);
223  }
224  else if(euclideanDist(center,a) > euclideanDist(center,c))
225  {
226  posTriangle[nbrTriangle].direction=a;
227  //line(img,center,a,Scalar(0,125,0),2,8,0);
228 
229  }
230  else
231  {
232  posTriangle[nbrTriangle].direction=c;
233  //line(img,center,c,Scalar(0,125,0),2,8,0);
234  }
235  posTriangle[nbrTriangle].angle=calculAngle(&posTriangle[nbrTriangle]);
236 
237  nbrTriangle++;
238 
239  }
240  }
241  return nbrTriangle;
242 }
243 
244 void draw_position(Image *imgInput, Image *imgOutput, Position *positionRobot) // img E/S pos : E
245 {
246  if(imgInput!=imgOutput)
247  {
248  *imgOutput=imgInput->clone();
249  }
250  line(*imgOutput,positionRobot->center,positionRobot->direction,Scalar(0,125,0),2,8,0);
251 }
252 
253 float calculAngle(Position * positionRobot) // position en entree
254 {
255  float a = positionRobot->direction.x - positionRobot->center.x;
256  float b = positionRobot->direction.y - positionRobot->center.y ;
257  float angle = atan2(b,a);
258  return angle * 180.f/M_PI;
259 
260 }
void compress_image(Image *imgInput, Jpg *imageCompress)
Détecte la position d&#39;un robot.
Definition: image.cpp:164
void get_image(Camera *camera, Image *monImage, const char *fichier)
Capture une image avec la camera passée en entrée. En cas de test sans camera, la fonction charge une...
Definition: image.cpp:93
Point center
Definition: image.h:70
float angle
Definition: image.h:72
#define WIDTH
Definition: image.h:44
void close_camera(Camera *camera)
Ferme la camera passé en paramètre.
Definition: image.cpp:112
int cropArena(Image *imgInput, Image *imgOutput, Arene *AreneInput)
Definition: image.cpp:150
Rect Arene
Definition: image.h:66
Mat Image
Definition: image.h:55
int detect_arena(Image *monImage, Arene *rectangle)
Détecte une arène dans une image fournis en paramètre.
Definition: image.cpp:126
int open_camera(Camera *camera)
Ouvre une camera.
Definition: image.cpp:58
Functions for image treatment.
Definition: image.h:69
int detect_position(Image *imgInput, Position *posTriangle, Arene *monArene)
Détecte la position d&#39;un robot.
Definition: image.cpp:170
void draw_arena(Image *imgInput, Image *imgOutput, Arene *monArene)
Dessine le plus petit rectangle contenant l&#39;arène.
Definition: image.cpp:51
float euclideanDist(Point &p, Point &q)
Definition: image.cpp:159
vector< unsigned char > Jpg
Definition: image.h:67
RaspiCam_Cv Camera
Definition: image.h:58
float calculAngle(Position *positionRobot)
Definition: image.cpp:253
#define HEIGHT
Definition: image.h:45
void draw_position(Image *imgInput, Image *imgOutput, Position *positionRobot)
Dessine sur une image en entrée la position d&#39;un robot et sa direction.
Definition: image.cpp:244
Point direction
Definition: image.h:71