Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
tutorial-munkres-assignment.cpp
1 
3 // Display
4 #include <visp3/gui/vpDisplayD3D.h>
5 #include <visp3/gui/vpDisplayGDI.h>
6 #include <visp3/gui/vpDisplayGTK.h>
7 #include <visp3/gui/vpDisplayOpenCV.h>
8 #include <visp3/gui/vpDisplayX.h>
9 
10 #include <visp3/core/vpColor.h>
11 
12 // Munkres
13 #include <visp3/core/vpMunkres.h>
14 
15 // Math
16 #include <visp3/core/vpUniRand.h>
17 
18 int main()
19 {
20 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) && \
21  (!defined(_MSC_VER) || ( (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) && (_MSC_VER >= 1911) ) )
22 
23 #if defined(VISP_HAVE_DISPLAY)
24  // Create base img
25  vpImage<unsigned char> I(480, 640, 255);
26 
27  // Generate random points
29  vpUniRand rand{};
30  std::vector<vpImagePoint> rand_ips{};
31  while (rand_ips.size() < 10) {
32  rand_ips.emplace_back(rand.uniform(10, I.getHeight() - 10), rand.uniform(10, I.getWidth() - 10));
33  }
35 
36  try {
37  // Init display
38  const auto disp_scale_type = vpDisplay::SCALE_AUTO;
39 #if defined(VISP_HAVE_X11)
40  vpDisplayX d(I, disp_scale_type);
41 #elif defined(VISP_HAVE_GDI)
42  vpDisplayGDI d(I, disp_scale_type);
43 #elif defined(VISP_HAVE_OPENCV)
44  vpDisplayOpenCV d(I, disp_scale_type);
45 #elif defined(VISP_HAVE_GTK)
46  vpDisplayGTK d(I, disp_scale_type);
47 #elif defined(VISP_HAVE_D3D9)
48  vpDisplayD3D d(I, disp_scale_type);
49 #else
50  std::cout << "No image viewer is available..." << std::endl;
51 #endif
52  vpDisplay::setTitle(I, "Munkres Assignment Algorithm");
53 
54  // Local helper to display a point in the image
55  auto display_point = [&I](const vpImagePoint &ip, const vpColor &color) {
56  I.display->displayCircle(ip, 5, color, true, 1);
57  };
58 
60 
61  auto disp_lane{0};
62  vpDisplay::displayText(I, 15 * ++disp_lane, 15, "Left click to add a point", vpColor::black);
63  vpDisplay::displayText(I, 15 * ++disp_lane, 15, "Middle click to continue (run Munkres)", vpColor::black);
64  vpDisplay::displayText(I, 15 * ++disp_lane, 15, "Right click to quit", vpColor::black);
65 
66  std::for_each(begin(rand_ips), end(rand_ips), std::bind(display_point, std::placeholders::_1, vpColor::red));
68 
69  // Ask user to clic on point
71  std::vector<vpImagePoint> user_ips{};
73  while (button != vpMouseButton::button2) {
74  vpImagePoint ip{};
75  vpDisplay::getClick(I, ip, button, true);
76  if (button == vpMouseButton::button1) {
77  user_ips.push_back(ip);
78  } else if (button == vpMouseButton::button3) {
79  return EXIT_SUCCESS;
80  }
81 
82  std::for_each(begin(user_ips), end(user_ips), std::bind(display_point, std::placeholders::_1, vpColor::green));
83 
85  }
87 
88  // Prepare Munkres (init cost matrix with random ip / user ip distances)
90  std::vector<std::vector<double> > cost_matrix(rand_ips.size(), std::vector<double>(user_ips.size()));
91  for (auto i = 0u; i < rand_ips.size(); i++) {
92  for (auto j = 0u; j < user_ips.size(); j++) {
93  cost_matrix.at(i).at(j) = vpImagePoint::distance(rand_ips.at(i), user_ips.at(j));
94  }
95  }
97 
98  // Display results
100  std::for_each(begin(rand_ips), end(rand_ips), std::bind(display_point, std::placeholders::_1, vpColor::red));
101  std::for_each(begin(user_ips), end(user_ips), std::bind(display_point, std::placeholders::_1, vpColor::green));
102 
104  for (const auto &[i, j] : vpMunkres::run(cost_matrix)) {
105  I.display->displayLine(rand_ips.at(i), user_ips.at(j), vpColor::blue, 1);
106  }
108 
109  vpDisplay::displayText(I, 15, 15, "Click to quit", vpColor::black);
110  vpDisplay::flush(I);
112 
113  } catch (const vpException &e) {
114  std::cout << "Catch an exception: " << e << std::endl;
115  }
116 #endif // defined(VISP_HAVE_DISPLAY)
117 #endif
118  return EXIT_SUCCESS;
119 }
vpDisplay * display
Definition: vpImage.h:144
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static const vpColor black
Definition: vpColor.h:211
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:157
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:134
error that can be emited by ViSP classes.
Definition: vpException.h:71
static const vpColor green
Definition: vpColor.h:220
static void flush(const vpImage< unsigned char > &I)
static const vpColor red
Definition: vpColor.h:217
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
Definition: vpDisplayD3D.h:106
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:134
static std::vector< std::pair< unsigned int, unsigned int > > run(std::vector< std::vector< Type > > costs)
Definition: vpMunkres.h:321
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
unsigned int getHeight() const
Definition: vpImage.h:188
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:87
Class for generating random numbers with uniform probability density.
Definition: vpUniRand.h:100
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
unsigned int getWidth() const
Definition: vpImage.h:246
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static const vpColor blue
Definition: vpColor.h:223