histo3D.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include <opencv2/core.hpp>
  2. #include <opencv2/imgproc.hpp>
  3. #include <opencv2/highgui.hpp>
  4. #include <iostream>
  5. using namespace std;
  6. using namespace cv;
  7. #ifdef HAVE_OPENCV_VIZ
  8. #include <opencv2/viz.hpp>
  9. const String keys =
  10. "{Aide h usage ? help | | print this message }"
  11. "{@arg1 | | Full path to color imag (3 channels)}"
  12. ;
  13. struct Histo3DData {
  14. Mat histogram;
  15. int seuil;
  16. double threshold;
  17. Ptr<viz::Viz3d> fen3D;
  18. int nbWidget;
  19. bool status;
  20. double maxH;
  21. int code;
  22. };
  23. void DrawHistogram3D(Histo3DData &);
  24. void AddSlidebar(String sliderName, String windowName, int sliderMin, int sliderMax, int valeurDefaut, int *sliderVal, void(*f)(int, void *), void *r);
  25. void UpdateThreshold(int , void * r);
  26. void KeyboardViz3d(const viz::KeyboardEvent &w, void *t);
  27. void DrawHistogram3D(Histo3DData &h)
  28. {
  29. //! [get_cube_size]
  30. int planSize = (int)h.histogram.step1(0);
  31. int cols = (int)h.histogram.step1(1);
  32. int rows = (int)planSize / cols;
  33. int plans = (int)h.histogram.total() / planSize;
  34. h.fen3D->removeAllWidgets();
  35. h.nbWidget=0;
  36. if (h.nbWidget==0)
  37. h.fen3D->showWidget("Axis", viz::WCoordinateSystem(10));
  38. //! [get_cube_size]
  39. //! [get_cube_values]
  40. for (int k = 0; k < plans; k++)
  41. {
  42. for (int i = 0; i < rows; i++)
  43. {
  44. for (int j = 0; j < cols; j++)
  45. {
  46. double x = h.histogram.at<float>(k, i, j);
  47. if (x >= h.threshold)
  48. {
  49. double r=std::max(x/h.maxH,0.1);
  50. viz::WCube s(Point3d(k - r / 2, i - r / 2, j - r / 2), Point3d(k + r / 2, i + r / 2, j + r / 2), false, viz::Color(j / double(plans) * 255, i / double(rows) * 255, k / double(cols) * 255));
  51. h.fen3D->showWidget(format("I3d%d", h.nbWidget++), s);
  52. }
  53. }
  54. }
  55. }
  56. //! [get_cube_values]
  57. h.status = false;
  58. }
  59. //! [viz_keyboard_callback]
  60. void KeyboardViz3d(const viz::KeyboardEvent &w, void *t)
  61. {
  62. Histo3DData *x=(Histo3DData *)t;
  63. if (w.action)
  64. cout << "you pressed "<< w.symbol<< " in viz window "<<x->fen3D->getWindowName()<<"\n";
  65. x->code= w.code;
  66. switch (w.code) {
  67. case '/':
  68. x->status=true;
  69. x->threshold *= 0.9;
  70. break;
  71. case '*':
  72. x->status = true;
  73. x->threshold *= 1.1;
  74. break;
  75. }
  76. if (x->status)
  77. {
  78. cout << x->threshold << "\n";
  79. DrawHistogram3D(*x);
  80. }
  81. }
  82. //! [viz_keyboard_callback]
  83. void AddSlidebar(String sliderName, String windowName, int sliderMin, int sliderMax, int defaultSlider, int *sliderVal, void(*f)(int, void *), void *r)
  84. {
  85. createTrackbar(sliderName, windowName, sliderVal, 1, f, r);
  86. setTrackbarMin(sliderName, windowName, sliderMin);
  87. setTrackbarMax(sliderName, windowName, sliderMax);
  88. setTrackbarPos(sliderName, windowName, defaultSlider);
  89. }
  90. void UpdateThreshold(int , void * r)
  91. {
  92. Histo3DData *h = (Histo3DData *)r;
  93. h->status=true;
  94. h->threshold = h->seuil/1000000.0;
  95. cout<<"Widget : "<<h->nbWidget<<","<< h->threshold<<"\n";
  96. }
  97. int main (int argc,char **argv)
  98. {
  99. //! [command_line_parser]
  100. CommandLineParser parser(argc, argv, keys);
  101. if (parser.has("help"))
  102. {
  103. parser.printMessage();
  104. return 0;
  105. }
  106. String nomFic = parser.get<String>(0);
  107. Mat img;
  108. if (nomFic.length() != 0)
  109. {
  110. img = imread(nomFic, IMREAD_COLOR);
  111. if (img.empty())
  112. {
  113. cout << "Image does not exist!";
  114. return 0;
  115. }
  116. }
  117. //! [command_line_parser]
  118. //! [synthetic_image]
  119. else
  120. {
  121. img = Mat(512,512,CV_8UC3);
  122. parser.printMessage();
  123. RNG r;
  124. r.fill(img(Rect(0, 0, 256, 256)), RNG::NORMAL, Vec3b(60, 40, 50), Vec3b(10, 5, 20));
  125. r.fill(img(Rect(256, 0, 256, 256)), RNG::NORMAL, Vec3b(160, 10, 50), Vec3b(20, 5, 10));
  126. r.fill(img(Rect(0, 256, 256, 256)), RNG::NORMAL, Vec3b(90, 100, 50), Vec3b(10, 20, 20));
  127. r.fill(img(Rect(256, 256, 256, 256)), RNG::NORMAL, Vec3b(100, 10, 150), Vec3b(10, 5, 40));
  128. }
  129. //! [synthetic_image]
  130. //! [calchist_for_histo3d]
  131. Histo3DData h;
  132. h.status=true;
  133. h.seuil=90;
  134. h.threshold= h.seuil/1000000.0;
  135. float hRange[] = { 0, 256 };
  136. const float* etendu[] = { hRange, hRange,hRange };
  137. int hBins = 32;
  138. int histSize[] = { hBins, hBins , hBins };
  139. int channel[] = { 2, 1,0 };
  140. calcHist(&img, 1, channel, Mat(), h.histogram, 3, histSize, etendu, true, false);
  141. normalize(h.histogram, h.histogram, 100.0/(img.total()), 0, NORM_MINMAX, -1, Mat());
  142. minMaxIdx(h.histogram,NULL,&h.maxH,NULL,NULL);
  143. //! [calchist_for_histo3d]
  144. //! [slide_bar_for_thresh]
  145. namedWindow("Image");
  146. imshow("Image",img);
  147. AddSlidebar("threshold","Image",0,100,h.seuil,&h.seuil, UpdateThreshold,&h);
  148. waitKey(30);
  149. //! [slide_bar_for_thresh]
  150. //! [manage_viz_imshow_window]
  151. h.fen3D = makePtr<viz::Viz3d>("3D Histogram");
  152. h.nbWidget=0;
  153. h.fen3D->registerKeyboardCallback(KeyboardViz3d,&h);
  154. DrawHistogram3D(h);
  155. while (h.code!=27)
  156. {
  157. h.fen3D->spinOnce(1);
  158. if (h.status)
  159. DrawHistogram3D(h);
  160. if (h.code!=27)
  161. h.code= waitKey(30);
  162. }
  163. //! [manage_viz_imshow_window]
  164. return 0;
  165. }
  166. #else
  167. int main(int argc, char **argv)
  168. {
  169. cout << " you need VIZ module\n";
  170. return 0;
  171. }
  172. #endif