Visual Servoing Platform  version 3.5.1 under development (2023-09-22)
vpMeTracker.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2019 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  * Description:
31  * Moving edges.
32  */
33 
39 #include <visp3/core/vpColor.h>
40 #include <visp3/core/vpDisplay.h>
41 #include <visp3/me/vpMeTracker.h>
42 
43 #include <algorithm>
44 #include <visp3/core/vpDebug.h>
45 #include <visp3/core/vpTrackingException.h>
46 
47 #define DEBUG_LEVEL1 0
48 #define DEBUG_LEVEL2 0
49 
51 {
53  p.resize(2);
55 }
56 
58  : list(), me(NULL), init_range(1), nGoodElement(0), m_mask(NULL), selectDisplay(vpMeSite::NONE)
59 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
60  ,
61  query_range(0), display_point(false)
62 #endif
63 {
64  init();
65 }
66 
68  : vpTracker(meTracker), list(), me(NULL), init_range(1), nGoodElement(0), m_mask(NULL), selectDisplay(vpMeSite::NONE)
69 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
70  ,
71  query_range(0), display_point(false)
72 #endif
73 {
74  init();
75 
76  me = meTracker.me;
77  list = meTracker.list;
78  nGoodElement = meTracker.nGoodElement;
79  init_range = meTracker.init_range;
80  selectDisplay = meTracker.selectDisplay;
81 
82 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
83  display_point = meTracker.display_point;
84  query_range = meTracker.query_range;
85 #endif
86 }
87 
89 {
90  nGoodElement = 0;
91  list.clear();
92 }
93 
95 
97 {
98  list = p_me.list;
99  me = p_me.me;
101  init_range = p_me.init_range;
102  nGoodElement = p_me.nGoodElement;
103 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
104  query_range = p_me.query_range;
106 #endif
107  return *this;
108 }
109 
110 static bool isSuppressZero(const vpMeSite &P) { return (P.getState() == vpMeSite::NO_SUPPRESSION); }
111 
113 {
114  unsigned int number_signal = 0;
115 
116  // Loop through all the points tracked from the contour
117  number_signal = static_cast<unsigned int>(std::count_if(list.begin(), list.end(), isSuppressZero));
118  return number_signal;
119 }
120 
121 unsigned int vpMeTracker::totalNumberOfSignal() { return (unsigned int)list.size(); }
122 
123 bool vpMeTracker::inMask(const vpImage<bool> *mask, unsigned int i, unsigned int j)
124 {
125  try {
126  return (mask == NULL || mask->getValue(i, j));
127  }
128  catch (vpException &) {
129  return false;
130  }
131 }
132 
133 int vpMeTracker::outOfImage(int i, int j, int half, int rows, int cols)
134 {
135  return (!((i > half + 2) && (i < rows - (half + 2)) && (j > half + 2) && (j < cols - (half + 2))));
136 }
137 
138 int vpMeTracker::outOfImage(const vpImagePoint &iP, int half, int rows, int cols)
139 {
140  int i = vpMath::round(iP.get_i());
141  int j = vpMath::round(iP.get_j());
142  return (!((i > half + 2) && (i < rows - (half + 2)) && (j > half + 2) && (j < cols - (half + 2))));
143 }
144 
146 {
147  if (!me) {
148  vpDERROR_TRACE(2, "Tracking error: Moving edges not initialized");
149  throw(vpTrackingException(vpTrackingException::initializationError, "Moving edges not initialized"));
150  }
151 
152  // Must set range to 0
153  unsigned int range_tmp = me->getRange();
155 
156  nGoodElement = 0;
157 
158  // Loop through list of sites to track
159  for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end(); ++it) {
160  vpMeSite refp = *it; // current reference pixel
161 
162  // If element hasn't been suppressed
163  if (refp.getState() == vpMeSite::NO_SUPPRESSION) {
164  try {
165  refp.track(I, me, false);
166  }
167  catch (...) {
168  // EM verifier quel signal est de sortie !!!
169  vpERROR_TRACE("Error caught");
170  throw;
171  }
172  if (refp.getState() == vpMeSite::NO_SUPPRESSION)
173  nGoodElement++;
174  }
175 
176  *it = refp;
177  }
178 
179  me->setRange(range_tmp);
180 }
181 
183 {
184  if (!me) {
185  vpDERROR_TRACE(2, "Tracking error: Moving edges not initialized");
186  throw(vpTrackingException(vpTrackingException::initializationError, "Moving edges not initialized"));
187  }
188 
189  if (list.empty()) {
190  vpDERROR_TRACE(2, "Tracking error: too few pixel to track");
191  throw(vpTrackingException(vpTrackingException::notEnoughPointError, "Too few pixel to track"));
192  }
193 
194  nGoodElement = 0;
195 
196  // Loop through list of sites to track
197  std::list<vpMeSite>::iterator it = list.begin();
198  while (it != list.end()) {
199  vpMeSite s = *it; // current reference pixel
200 
201  // If element hasn't been suppressed
202  if (s.getState() == vpMeSite::NO_SUPPRESSION) {
203 
204  try {
205  s.track(I, me, true);
206  }
207  catch (...) {
209  }
210 
211  if (vpMeTracker::inMask(m_mask, s.i, s.j)) {
212  if (s.getState() != vpMeSite::THRESHOLD) {
213  nGoodElement++;
214  }
215  *it = s;
216  ++it;
217  }
218  else {
219  // Site outside mask: it is no more tracked.
220  it = list.erase(it);
221  }
222  }
223  else {
224  ++it;
225  }
226  }
227 }
228 
230 {
231  for (std::list<vpMeSite>::const_iterator it = list.begin(); it != list.end(); ++it) {
232  vpMeSite p_me = *it;
233  p_me.display(I);
234  }
235 }
236 
238 {
239  for (std::list<vpMeSite>::const_iterator it = list.begin(); it != list.end(); ++it) {
240  vpMeSite p_me = *it;
241  p_me.display(I);
242  }
243 }
244 
245 void vpMeTracker::display(const vpImage<unsigned char> &I, vpColVector &w, unsigned int &index_w)
246 {
247  for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end(); ++it) {
248  vpMeSite P = *it;
249 
250  if (P.getState() == vpMeSite::NO_SUPPRESSION) {
251  P.weight = w[index_w];
252  index_w++;
253  }
254 
255  *it = P;
256  }
257  display(I);
258 }
259 
260 #undef DEBUG_LEVEL1
261 #undef DEBUG_LEVEL2
Implementation of column vector and the associated operations.
Definition: vpColVector.h:167
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:351
error that can be emitted by ViSP classes.
Definition: vpException.h:59
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
double get_j() const
Definition: vpImagePoint.h:125
double get_i() const
Definition: vpImagePoint.h:114
Type getValue(unsigned int i, unsigned int j) const
Definition: vpImage.h:1592
static int round(double x)
Definition: vpMath.h:323
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
Definition: vpMeSite.h:65
int j
Coordinates along j of a site.
Definition: vpMeSite.h:98
@ THRESHOLD
Point removed due to a threshold problem.
Definition: vpMeSite.h:88
@ NO_SUPPRESSION
Point used by the tracker.
Definition: vpMeSite.h:83
double weight
Uncertainty of point given as a probability between 0 and 1.
Definition: vpMeSite.h:112
void display(const vpImage< unsigned char > &I)
Definition: vpMeSite.cpp:415
@ NONE
Not displayed.
Definition: vpMeSite.h:72
int i
Coordinate along i of a site.
Definition: vpMeSite.h:96
vpMeSiteState getState() const
Definition: vpMeSite.h:261
void track(const vpImage< unsigned char > &im, const vpMe *me, bool test_likelihood=true)
Definition: vpMeSite.cpp:305
void setState(const vpMeSiteState &flag)
Definition: vpMeSite.h:247
Contains abstract elements for a Distance to Feature type feature.
Definition: vpMeTracker.h:60
void initTracking(const vpImage< unsigned char > &I)
const vpImage< bool > * m_mask
Mask used to disable tracking on a part of image.
Definition: vpMeTracker.h:80
unsigned int numberOfSignal()
virtual ~vpMeTracker()
Definition: vpMeTracker.cpp:94
int nGoodElement
Number of good moving-edges that are tracked.
Definition: vpMeTracker.h:78
vpMeSite::vpMeSiteDisplayType selectDisplay
Definition: vpMeTracker.h:86
int outOfImage(int i, int j, int half, int row, int cols)
void track(const vpImage< unsigned char > &I)
unsigned int totalNumberOfSignal()
std::list< vpMeSite > list
Definition: vpMeTracker.h:72
void display(const vpImage< unsigned char > &I)
unsigned int init_range
Initial range.
Definition: vpMeTracker.h:76
static bool inMask(const vpImage< bool > *mask, unsigned int i, unsigned int j)
bool display_point
Definition: vpMeTracker.h:288
vpMeTracker & operator=(vpMeTracker &f)
Definition: vpMeTracker.cpp:96
void reset()
Definition: vpMeTracker.cpp:88
vpMe * me
Moving edges initialisation parameters.
Definition: vpMeTracker.h:74
void setRange(const unsigned int &r)
Definition: vpMe.h:383
unsigned int getRange() const
Definition: vpMe.h:273
Class that defines what is a feature generic tracker.
Definition: vpTracker.h:60
void init()
Default initialization.
Definition: vpTracker.cpp:44
vpColVector p
Definition: vpTracker.h:68
Error that can be emitted by the vpTracker class and its derivatives.
@ notEnoughPointError
Not enough point to track.
@ initializationError
Tracker initialization error.
#define vpDERROR_TRACE
Definition: vpDebug.h:459
#define vpERROR_TRACE
Definition: vpDebug.h:388