/sansCamera.cpp

http://trait-im-terrainfoot.googlecode.com/ · C++ · 304 lines · 241 code · 30 blank · 33 comment · 12 complexity · 88b8e60451a8411874568db7f85c7a36 MD5 · raw file

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <iostream>
  5. #include <cxcore.h>
  6. #include <cvaux.h>
  7. #include <cv.h>
  8. #include <highgui.h>
  9. CvPoint coordCalibrage[17];
  10. CvPoint balleTerrain;
  11. CvPoint balleEcran;
  12. CvPoint centreButEcran;
  13. int iSaisie = 0;
  14. bool afficherText = true;
  15. CvMat* homographyMat = cvCreateMat(3, 3, CV_32FC1);
  16. void findHomographyPerso(CvPoint * pts_ecran, CvMat* matHomography);
  17. void useHomography(CvMat* matHomography);
  18. void mouseCallback(int event, int x, int y, int flags, void* param);
  19. double distance(CvPoint p1, CvPoint p2);
  20. void dessinerDistance(IplImage *& img, int rayon, double d);
  21. int main(int argc, char *argv[]) {
  22. int rayon = 9;
  23. int height, width, step, channels;
  24. uchar *data;
  25. IplImage* img = 0;
  26. if (argc < 2) {
  27. printf("Usage: main <image-file-name>\n\7");
  28. exit(0);
  29. }
  30. // load an image
  31. img = cvLoadImage(argv[1], 1);
  32. if (!img) {
  33. printf("Could not load image file: %s\n", argv[1]);
  34. exit(0);
  35. }
  36. CvMat* matPointEcran = cvCreateMat(3, 1, CV_32FC1);
  37. CvMat* matPointTerrainReel = cvCreateMat(3, 1, CV_32FC1);
  38. // get the image data
  39. height = img->height;
  40. width = img->width;
  41. step = img->widthStep;
  42. channels = img->nChannels;
  43. data = (uchar *) img->imageData;
  44. printf("Processing a %dx%d image with %d channels\n", height, width,
  45. channels);
  46. // create a window
  47. cvNamedWindow("Terrain de Foot", CV_WINDOW_AUTOSIZE);
  48. cvMoveWindow("Terrain de Foot", 100, 100);
  49. // show the image
  50. cvShowImage("Terrain de Foot", img);
  51. // Set up the callback
  52. cvSetMouseCallback("Terrain de Foot", mouseCallback, (void*) img);
  53. while (true) {
  54. if (afficherText == true) {
  55. switch (iSaisie) {
  56. case 0:
  57. std::cout
  58. << "* Cliquez sur le coin superieur droit du terrain\n";
  59. afficherText = false;
  60. break;
  61. case 1:
  62. std::cout
  63. << "* Cliquez sur le coin superieur gauche du terrain\n";
  64. afficherText = false;
  65. break;
  66. case 2:
  67. std::cout
  68. << "* Cliquez sur le coin inferieur droit du terrain\n";
  69. afficherText = false;
  70. break;
  71. case 3:
  72. std::cout
  73. << "* Cliquez sur le coin inferieur gauche du terrain\n";
  74. afficherText = false;
  75. break;
  76. case 4:
  77. std::cout << "* Cliquez sur le milieu droit\n";
  78. afficherText = false;
  79. break;
  80. case 5:
  81. std::cout << "* Cliquez sur le milieu gauche\n";
  82. afficherText = false;
  83. break;
  84. case 6:
  85. std::cout << "* Cliquez sur le milieu centre\n";
  86. afficherText = false;
  87. break;
  88. case 7:
  89. std::cout << "* Cliquez sur le penalty superieur\n";
  90. afficherText = false;
  91. break;
  92. case 8:
  93. std::cout << "* Cliquez sur le poteau superieur droit\n";
  94. afficherText = false;
  95. break;
  96. case 9:
  97. std::cout << "* Cliquez sur le poteau superieur gauche\n";
  98. afficherText = false;
  99. break;
  100. case 10:
  101. std::cout
  102. << "* Cliquez sur le coin de la surface superieur droit\n";
  103. afficherText = false;
  104. break;
  105. case 11:
  106. std::cout
  107. << "* Cliquez sur le coin de la surface superieur gauche\n";
  108. afficherText = false;
  109. break;
  110. case 12:
  111. std::cout << "* Cliquez sur le point de penalty inferieur\n";
  112. afficherText = false;
  113. break;
  114. case 13:
  115. std::cout << "* Cliquez sur le poteau inferieur droite\n";
  116. afficherText = false;
  117. break;
  118. case 14:
  119. std::cout << "* Cliquez sur le poteau inferieur gauche\n";
  120. afficherText = false;
  121. break;
  122. case 15:
  123. std::cout
  124. << "* Cliquez sur le coin de la surface inferieur droit\n";
  125. afficherText = false;
  126. break;
  127. case 16:
  128. std::cout
  129. << "* Cliquez sur le coin de la surface inferieur gauche\n";
  130. afficherText = false;
  131. break;
  132. case 17:
  133. afficherText = false;
  134. findHomographyPerso(coordCalibrage, homographyMat);
  135. std::cout << "\n* Cliquez sur la balle\n";
  136. break;
  137. case 100:
  138. img = cvLoadImage(argv[1], 1);
  139. std::cout << " > Calcul de la distance de la balle au but : \n";
  140. //Modification coordonné Balle
  141. cvmSet(matPointEcran, 0, 0, balleEcran.x);
  142. cvmSet(matPointEcran, 1, 0, balleEcran.y);
  143. cvmSet(matPointEcran, 2, 0, 1);
  144. cvMatMul(homographyMat, matPointEcran, matPointTerrainReel);
  145. balleTerrain.x = cvmGet(matPointTerrainReel, 0, 0) / cvmGet(
  146. matPointTerrainReel, 2, 0);
  147. balleTerrain.y = cvmGet(matPointTerrainReel, 1, 0) / cvmGet(
  148. matPointTerrainReel, 2, 0);
  149. CvPoint destination = cvPoint(45,0);
  150. double d = distance(balleTerrain, destination);
  151. std::cout << "\n distance = " << d << " metres\n";
  152. dessinerDistance(img, rayon, d);
  153. afficherText = false;
  154. break;
  155. }
  156. }
  157. // wait for a ESC key for exit
  158. if (cvWaitKey(15) == 27)
  159. break;
  160. }
  161. // release the image
  162. cvReleaseImage(&img);
  163. return 0;
  164. }
  165. void mouseCallback(int event, int x, int y, int flags, void* param) {
  166. switch (event) {
  167. case CV_EVENT_LBUTTONDOWN:
  168. if (iSaisie < 17) {
  169. coordCalibrage[iSaisie] = cvPoint(x, y);
  170. iSaisie++;
  171. } else {
  172. balleEcran = cvPoint(x, y);
  173. balleTerrain = cvPoint(balleEcran.x,balleEcran.y);
  174. iSaisie = 100;
  175. }
  176. afficherText = true;
  177. break;
  178. }
  179. }
  180. double distance(CvPoint p1, CvPoint p2) {
  181. // double add = pow(p1.x + p2.x, 2) + pow(p1.y + p2.y, 2);
  182. // return sqrt(add);
  183. double add = pow(abs(p1.x - p2.x), 2) + pow(abs(p1.y - p2.y), 2);
  184. return sqrt(add);
  185. }
  186. void findHomographyPerso(CvPoint * pts_ecran, CvMat* matHomography) {
  187. int nbPoints = 17;
  188. float largeurTerrain = 90;
  189. float longueurTerrain = 120;
  190. //Creatin des deux matrices representant des points sur le systeme de coordonnees du terrain et de l'ecran
  191. CvMat* matPointsTerrainReel = cvCreateMat(nbPoints, 2, CV_32FC1);
  192. CvMat *matPointsEcran = cvCreateMat(nbPoints, 2, CV_32FC1);
  193. for (int i = 0; i < nbPoints; i++) {
  194. cvmSet(matPointsEcran, i, 0, (double) pts_ecran[i].x);
  195. cvmSet(matPointsEcran, i, 1, (double) pts_ecran[i].y);
  196. }
  197. // for (int i = 0; i < nbPoints; i++) {
  198. // float x = cvmGet(matPointsEcran,i, 0);
  199. // float y = cvmGet(matPointsEcran,i, 1);
  200. // std::cout << x << " & " << y << std::endl;
  201. // }
  202. //corner sup droit
  203. cvmSet(matPointsTerrainReel, 0, 0, (double) 0);
  204. cvmSet(matPointsTerrainReel, 0, 1, (double) 0);
  205. //corner sup gauche
  206. cvmSet(matPointsTerrainReel, 1, 0, (double) largeurTerrain);
  207. cvmSet(matPointsTerrainReel, 1, 1, (double) 0);
  208. //corner inf droit
  209. cvmSet(matPointsTerrainReel, 2, 0, (double) 0);
  210. cvmSet(matPointsTerrainReel, 2, 1, (double) longueurTerrain);
  211. //corner inf gauche
  212. cvmSet(matPointsTerrainReel, 3, 0, (double) largeurTerrain);
  213. cvmSet(matPointsTerrainReel, 3, 1, (double) longueurTerrain);
  214. //milieu droit
  215. cvmSet(matPointsTerrainReel, 4, 0, (double) 0);
  216. cvmSet(matPointsTerrainReel, 4, 1, (double) longueurTerrain / 2);
  217. //milieu gauche
  218. cvmSet(matPointsTerrainReel, 5, 0, (double) largeurTerrain);
  219. cvmSet(matPointsTerrainReel, 5, 1, (double) longueurTerrain / 2);
  220. //milieu centre
  221. cvmSet(matPointsTerrainReel, 6, 0, (double) largeurTerrain / 2);
  222. cvmSet(matPointsTerrainReel, 6, 1, (double) longueurTerrain / 2);
  223. //Penalty sup
  224. cvmSet(matPointsTerrainReel, 7, 0, (double) largeurTerrain / 2);
  225. cvmSet(matPointsTerrainReel, 7, 1, (double) 11);
  226. //Poteau sup droit
  227. cvmSet(matPointsTerrainReel, 8, 0, (double) (largeurTerrain / 2) - 3.65);
  228. cvmSet(matPointsTerrainReel, 8, 1, (double) 0);
  229. //Poteau sup gauche
  230. cvmSet(matPointsTerrainReel, 9, 0, (double) (largeurTerrain / 2) + 3.65);
  231. cvmSet(matPointsTerrainReel, 9, 1, (double) 0);
  232. //Coin surface sup droit
  233. cvmSet(matPointsTerrainReel, 10, 0, (double) (largeurTerrain / 2) - 3.65
  234. - 16.5);
  235. cvmSet(matPointsTerrainReel, 10, 1, (double) 16.5);
  236. //Coin surface sup gauche
  237. cvmSet(matPointsTerrainReel, 11, 0, (double) (largeurTerrain / 2) + 3.65
  238. + 16.5);
  239. cvmSet(matPointsTerrainReel, 11, 1, (double) 16.5);
  240. //Penalty inf
  241. cvmSet(matPointsTerrainReel, 12, 0, (double) largeurTerrain / 2);
  242. cvmSet(matPointsTerrainReel, 12, 1, (double) longueurTerrain - 11);
  243. //Poteau inf droit
  244. cvmSet(matPointsTerrainReel, 13, 0, (double) (largeurTerrain / 2) - 3.65);
  245. cvmSet(matPointsTerrainReel, 13, 1, (double) longueurTerrain);
  246. //Poteau inf gauche
  247. cvmSet(matPointsTerrainReel, 14, 0, (double) (largeurTerrain / 2) + 3.65);
  248. cvmSet(matPointsTerrainReel, 14, 1, (double) longueurTerrain);
  249. //Coin surface inf droit
  250. cvmSet(matPointsTerrainReel, 15, 0, (double) (largeurTerrain / 2) - 3.65
  251. - 16.5);
  252. cvmSet(matPointsTerrainReel, 15, 1, (double) longueurTerrain - 16.5);
  253. //Coin surface inf gauche
  254. cvmSet(matPointsTerrainReel, 16, 0, (double) (largeurTerrain / 2) + 3.65
  255. + 16.5);
  256. cvmSet(matPointsTerrainReel, 16, 1, (double) longueurTerrain - 16.5);
  257. cvFindHomography(matPointsEcran, matPointsTerrainReel, matHomography);
  258. cvReleaseMat(&matPointsEcran);
  259. cvReleaseMat(&matPointsTerrainReel);
  260. }
  261. void dessinerDistance(IplImage *& img, int rayon, double d) {
  262. cvCircle(img, balleEcran, rayon, CV_RGB(255,0,0), 2, 8, 0);
  263. centreButEcran = cvPoint((coordCalibrage[8].x + (coordCalibrage[9].x
  264. - coordCalibrage[8].x) / 2.0), (coordCalibrage[8].y
  265. + (coordCalibrage[9].y - coordCalibrage[8].y) / 2.0));
  266. cvLine(img, balleEcran, centreButEcran, CV_RGB(255,0,0), 1, CV_AA);
  267. CvFont font;
  268. cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0.0, 1);
  269. char *strDistance = new char[256];
  270. sprintf(strDistance, "Disance : %lf m", d);
  271. cvPutText(img, strDistance, cvPoint(balleEcran.x + 10, balleEcran.y + 10),
  272. &font, cvScalar(127));
  273. cvShowImage("Terrain de Foot", img);
  274. }