File: tutorial-munkres-assignment.cpp

package info (click to toggle)
visp 3.7.0-7
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 166,380 kB
  • sloc: cpp: 392,705; ansic: 224,448; xml: 23,444; python: 13,701; java: 4,792; sh: 206; objc: 145; makefile: 118
file content (125 lines) | stat: -rw-r--r-- 4,006 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! \example tutorial-munkres-assignment.cpp

#include <functional>

#include <visp3/core/vpConfig.h>
// Display
#include <visp3/gui/vpDisplayFactory.h>

#include <visp3/core/vpColor.h>

// Munkres
#include <visp3/core/vpMunkres.h>

// Math
#include <visp3/core/vpUniRand.h>

int main()
{
  // Check if std:c++17 or higher
#if ((__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)))

#if defined(VISP_HAVE_DISPLAY)
#ifdef ENABLE_VISP_NAMESPACE
  using namespace VISP_NAMESPACE_NAME;
#endif
  // Create base img
  vpImage<unsigned char> I(480, 640, 255);

  // Generate random points
  //! [Rand_Img_Pts]
  vpUniRand rand {};
  std::vector<vpImagePoint> rand_ips {};
  while (rand_ips.size() < 10) {
    rand_ips.emplace_back(rand.uniform(10, I.getHeight() - 10), rand.uniform(10, I.getWidth() - 10));
  }
  //! [Rand_Img_Pts]

  // Init display
  const auto disp_scale_type = vpDisplay::SCALE_AUTO;
#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
  std::shared_ptr<vpDisplay> display = vpDisplayFactory::createDisplay(I, disp_scale_type);
#else
  vpDisplay *display = vpDisplayFactory::allocateDisplay(I, disp_scale_type);
#endif
  vpDisplay::setTitle(I, "Munkres Assignment Algorithm");
  try {
    // Local helper to display a point in the image
    auto display_point = [&I](const vpImagePoint &ip, const vpColor &color) {
      I.display->displayCircle(ip, 5, color, true, 1);
      };

    vpDisplay::display(I);

    auto disp_lane { 0 };
    vpDisplay::displayText(I, 15 * ++disp_lane, 15, "Left click to add a point", vpColor::black);
    vpDisplay::displayText(I, 15 * ++disp_lane, 15, "Middle click to continue (run Munkres)", vpColor::black);
    vpDisplay::displayText(I, 15 * ++disp_lane, 15, "Right click to quit", vpColor::black);

    std::for_each(begin(rand_ips), end(rand_ips), std::bind(display_point, std::placeholders::_1, vpColor::red));
    vpDisplay::flush(I);

    // Ask user to clic on point
    //! [User_Img_Pts]
    std::vector<vpImagePoint> user_ips {};
    vpMouseButton::vpMouseButtonType button {};
    while (button != vpMouseButton::button2) {
      vpImagePoint ip {};
      vpDisplay::getClick(I, ip, button, true);
      if (button == vpMouseButton::button1) {
        user_ips.push_back(ip);
      }
      else if (button == vpMouseButton::button3) {
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11) && defined(VISP_HAVE_DISPLAY)
        if (display != nullptr) {
          delete display;
        }
#endif
        return EXIT_SUCCESS;
      }

      std::for_each(begin(user_ips), end(user_ips), std::bind(display_point, std::placeholders::_1, vpColor::green));

      vpDisplay::flush(I);
    }
    //! [User_Img_Pts]

    // Prepare Munkres (init cost matrix with random ip / user ip distances)
    //! [Cost_Matrix]
    std::vector<std::vector<double> > cost_matrix(rand_ips.size(), std::vector<double>(user_ips.size()));
    for (auto i = 0u; i < rand_ips.size(); i++) {
      for (auto j = 0u; j < user_ips.size(); j++) {
        cost_matrix.at(i).at(j) = vpImagePoint::distance(rand_ips.at(i), user_ips.at(j));
      }
    }
    //! [Cost_Matrix]

    // Display results
    vpDisplay::display(I);
    std::for_each(begin(rand_ips), end(rand_ips), std::bind(display_point, std::placeholders::_1, vpColor::red));
    std::for_each(begin(user_ips), end(user_ips), std::bind(display_point, std::placeholders::_1, vpColor::green));

    //! [Run]
    for (const auto &[i, j] : vpMunkres::run(cost_matrix)) {
      I.display->displayLine(rand_ips.at(i), user_ips.at(j), vpColor::blue, 1);
    }
    //! [Run]

    vpDisplay::displayText(I, 15, 15, "Click to quit", vpColor::black);
    vpDisplay::flush(I);
    vpDisplay::getClick(I);

  }
  catch (const vpException &e) {
    std::cout << "Catch an exception: " << e << std::endl;
  }

#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11) && defined(VISP_HAVE_DISPLAY)
  if (display != nullptr) {
    delete display;
  }
#endif
#endif // defined(VISP_HAVE_DISPLAY)
#endif
  return EXIT_SUCCESS;
}