Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
tutorial-pf-curve-fitting-lms.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  */
30 
32 
33 #include <visp3/core/vpConfig.h>
34 #include <visp3/core/vpException.h>
35 #include <visp3/core/vpMouseButton.h>
36 #include <visp3/core/vpTime.h>
37 
38 #ifdef VISP_HAVE_DISPLAY
39 #include <visp3/gui/vpPlot.h>
40 #endif
41 
42 #include "vpTutoCommonData.h"
43 #include "vpTutoMeanSquareFitting.h"
44 #include "vpTutoParabolaModel.h"
45 #include "vpTutoSegmentation.h"
46 
47 #ifdef ENABLE_VISP_NAMESPACE
48 using namespace VISP_NAMESPACE_NAME;
49 #endif
50 
51 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) && defined(VISP_HAVE_DISPLAY)
52 int main(const int argc, const char *argv[])
53 {
54  tutorial::vpTutoCommonData data;
55  int returnCode = data.init(argc, argv);
56  if (returnCode != tutorial::vpTutoCommonData::SOFTWARE_CONTINUE) {
57  return returnCode;
58  }
59  tutorial::vpTutoMeanSquareFitting lmsFitter(data.m_degree, data.m_I_orig.getHeight(), data.m_I_orig.getWidth());
60  const unsigned int vertOffset = static_cast<unsigned int>(data.m_legendOffset.get_i());
61  const unsigned int horOffset = static_cast<unsigned int>(data.m_ipLegend.get_j());
62  const unsigned int legendLmsVert = data.m_I_orig.getHeight() - 2 * vertOffset;
63  const unsigned int legendLmsHor = horOffset;
64 
66 #ifdef VISP_HAVE_DISPLAY
67  unsigned int plotHeight = 350, plotWidth = 350;
68  int plotXpos = static_cast<int>(data.m_legendOffset.get_u());
69  int plotYpos = static_cast<int>(data.m_I_orig.getHeight() + 4. * data.m_legendOffset.get_v());
70  vpPlot plot(1, plotHeight, plotWidth, plotXpos, plotYpos, "Root mean-square error");
71  plot.initGraph(0, 1);
72  plot.setLegend(0, 0, "LMS estimator");
73  plot.setColor(0, 0, vpColor::gray);
74 #endif
76 
77  bool run = true;
78  unsigned int nbIter = 0;
79  double meanDtLMS = 0.;
80  double meanRootMeanSquareErrorLMS = 0.;
81  while (!data.m_grabber.end() && run) {
83  std::cout << "Iter " << nbIter << std::endl;
84  data.m_grabber.acquire(data.m_I_orig);
85 
86  // Perform color segmentation
87  tutorial::performSegmentationHSV(data);
88 
90  std::vector<vpImagePoint> edgePoints = tutorial::extractSkeleton(data);
91 
93  std::vector<vpImagePoint> noisyEdgePoints = tutorial::addSaltAndPepperNoise(edgePoints, data);
95 
96 #ifdef VISP_HAVE_DISPLAY
98  vpDisplay::display(data.m_I_orig);
99  vpDisplay::display(data.m_I_segmented);
100  vpDisplay::display(data.m_IskeletonNoisy);
101 #endif
102 
104  double tLms = vpTime::measureTimeMs();
106  lmsFitter.fit(noisyEdgePoints);
108  double dtLms = vpTime::measureTimeMs() - tLms;
109  double lmsRootMeanSquareError = lmsFitter.evaluate(edgePoints);
110  std::cout << " [Least-Mean Square method] " << std::endl;
111  std::cout << " Coeffs = [" << lmsFitter.getCoeffs().transpose() << " ]" << std::endl;
112  std::cout << " Root Mean Square Error = " << lmsRootMeanSquareError << " pixels" << std::endl;
113  std::cout << " Fitting duration = " << dtLms << " ms" << std::endl;
114  meanDtLMS += dtLms;
115  meanRootMeanSquareErrorLMS += lmsRootMeanSquareError;
116 
117 #ifdef VISP_HAVE_DISPLAY
118  // Update image overlay
119  lmsFitter.display<unsigned char>(data.m_IskeletonNoisy, vpColor::gray, legendLmsVert, legendLmsHor);
120 
121  // Update plot
122  plot.plot(0, 0, nbIter, lmsRootMeanSquareError);
123  // Display the images with overlayed info
124  data.displayLegend(data.m_I_orig);
125  vpDisplay::flush(data.m_I_orig);
126  vpDisplay::flush(data.m_I_segmented);
127  vpDisplay::flush(data.m_IskeletonNoisy);
128  run = data.manageClicks(data.m_I_orig, data.m_stepbystep);
129 #endif
130  ++nbIter;
131  }
132 
133  double iterAsDouble = static_cast<double>(nbIter);
134  std::cout << std::endl << std::endl << "-----[Statistics summary]-----" << std::endl;
135  std::cout << " [LMS method] " << std::endl;
136  std::cout << " Average Root Mean Square Error = " << meanRootMeanSquareErrorLMS / iterAsDouble << " pixels" << std::endl;
137  std::cout << " Average fitting duration = " << meanDtLMS / iterAsDouble << " ms" << std::endl;
138 
139 #ifdef VISP_HAVE_DISPLAY
140  if (data.m_grabber.end() && (!data.m_stepbystep)) {
142  vpDisplay::display(data.m_I_orig);
143  vpDisplay::displayText(data.m_I_orig, data.m_ipLegend, "End of sequence reached. Click to exit.", data.m_colorLegend);
144 
146  vpDisplay::flush(data.m_I_orig);
147 
149  vpDisplay::getClick(data.m_I_orig, true);
150  }
151 #endif
152  return 0;
153 }
154 #else
155 int main()
156 {
157  std::cerr << "ViSP must be compiled with C++ standard >= C++11 to use this tutorial." << std::endl;
158  std::cerr << "ViSP must also have a 3rd party enabling display features, such as X11 or OpenCV." << std::endl;
159  return EXIT_FAILURE;
160 }
161 #endif
static const vpColor gray
Definition: vpColor.h:214
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
Definition: vpPlot.h:112
VISP_EXPORT double measureTimeMs()