Visual Servoing Platform version 3.5.0
tutorial-munkres-assignment.cpp
1
2
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
18int 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);
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}
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:158
static const vpColor red
Definition: vpColor.h:217
static const vpColor black
Definition: vpColor.h:211
static const vpColor blue
Definition: vpColor.h:223
static const vpColor green
Definition: vpColor.h:220
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:107
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:135
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:135
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
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 void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
@ SCALE_AUTO
Definition: vpDisplay.h:183
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
static void displayCircle(const vpImage< unsigned char > &I, const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
error that can be emited by ViSP classes.
Definition: vpException.h:72
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
vpDisplay * display
Definition: vpImage.h:144
static std::vector< std::pair< unsigned int, unsigned int > > run(std::vector< std::vector< Type > > costs)
Definition: vpMunkres.h:321
Class for generating random numbers with uniform probability density.
Definition: vpUniRand.h:101