Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMeSite.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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
38
39#include <cmath> // std::fabs
40#include <limits> // numeric_limits
41#include <stdlib.h>
42#include <map>
43
44#include <visp3/core/vpTrackingException.h>
45#include <visp3/me/vpMe.h>
46#include <visp3/me/vpMeSite.h>
47
49
50#ifndef DOXYGEN_SHOULD_SKIP_THIS
51
52struct vpMeSiteHypothesis
53{
54 vpMeSiteHypothesis(vpMeSite *site, double l, double c) : site(site), likelihood(l), contrast(c)
55 { }
56
57 vpMeSite *site;
58 double likelihood;
59 double contrast;
60};
61
62static bool outsideImage(int i, int j, int half, int rows, int cols)
63{
64 int half_1 = half + 1;
65 int half_3 = half + 3;
66 return ((0 < (half_1 - i)) || (((i - rows) + half_3) > 0) || (0 < (half_1 - j)) || (((j - cols) + half_3) > 0));
67}
68#endif
69
71{
72 // Site components
73 m_alpha = 0.0;
74 m_convlt = 0.0;
75 m_weight = -1;
76 m_contrastThreshold = 10000.0;
77
78 m_selectDisplay = NONE;
79
80 // Pixel components
81 m_i = 0;
82 m_j = 0;
83 m_ifloat = m_i;
84 m_jfloat = m_j;
85
86 m_mask_sign = 1;
87
89
90 m_state = NO_SUPPRESSION;
91
92 m_index_prev = 90; // Middle index to have no effect on first image
93}
94
96 : m_i(0), m_j(0), m_ifloat(0), m_jfloat(0), m_mask_sign(1), m_alpha(0.), m_convlt(0.), m_normGradient(0),
97 m_weight(1), m_contrastThreshold(10000.0), m_selectDisplay(NONE), m_state(NO_SUPPRESSION), m_index_prev(90)
98{ }
99
100vpMeSite::vpMeSite(const double &ip, const double &jp)
101 : m_i(0), m_j(0), m_ifloat(0), m_jfloat(0), m_mask_sign(1), m_alpha(0.), m_convlt(0.), m_normGradient(0),
102 m_weight(1), m_contrastThreshold(10000.0), m_selectDisplay(NONE), m_state(NO_SUPPRESSION), m_index_prev(90)
103{
104 m_i = vpMath::round(ip);
105 m_j = vpMath::round(jp);
106 m_ifloat = ip;
107 m_jfloat = jp;
108}
109
111 : m_i(0), m_j(0), m_ifloat(0), m_jfloat(0), m_mask_sign(1), m_alpha(0.), m_convlt(0.), m_normGradient(0),
112 m_weight(1), m_contrastThreshold(10000.0), m_selectDisplay(NONE), m_state(NO_SUPPRESSION), m_index_prev(90)
113{
114 *this = mesite;
115}
116
117// More an Update than init
118// For points in meter form (to avoid approximations)
119void vpMeSite::init(const double &ip, const double &jp, const double &alphap)
120{
121 // Note: keep old value of m_convlt, contrast and threshold
122 m_selectDisplay = NONE;
123
124 m_ifloat = ip;
125 m_i = vpMath::round(ip);
126 m_jfloat = jp;
127 m_j = vpMath::round(jp);
128 m_alpha = alphap;
129 m_mask_sign = 1;
130 m_index_prev = 90;
131}
132
133// initialise with convolution()
134void vpMeSite::init(const double &ip, const double &jp, const double &alphap, const double &convltp)
135{
136 m_selectDisplay = NONE;
137 m_ifloat = ip;
138 m_i = static_cast<int>(ip);
139 m_jfloat = jp;
140 m_j = static_cast<int>(jp);
141 m_alpha = alphap;
142 m_convlt = convltp;
143 m_mask_sign = 1;
144 m_index_prev = 90;
145}
146
147// initialise with convolution and sign
148void vpMeSite::init(const double &ip, const double &jp, const double &alphap, const double &convltp, const int &sign)
149{
150 m_selectDisplay = NONE;
151 m_ifloat = ip;
152 m_i = static_cast<int>(ip);
153 m_jfloat = jp;
154 m_j = static_cast<int>(jp);
155 m_alpha = alphap;
156 m_convlt = convltp;
157 m_mask_sign = sign;
158 m_index_prev = 90;
159}
160
161// Initialise with convolution and sign.
162void vpMeSite::init(const double &ip, const double &jp, const double &alphap, const double &convltp, const int &sign, const double &contrastThreshold)
163{
164 m_selectDisplay = NONE;
165 m_ifloat = ip;
166 m_i = static_cast<int>(ip);
167 m_jfloat = jp;
168 m_j = static_cast<int>(jp);
169 m_alpha = alphap;
170 m_convlt = convltp;
171 m_mask_sign = sign;
172 m_contrastThreshold = contrastThreshold;
173 m_index_prev = 90;
174}
175
177{
178 m_i = m.m_i;
179 m_j = m.m_j;
180 m_ifloat = m.m_ifloat;
181 m_jfloat = m.m_jfloat;
183 m_alpha = m.m_alpha;
184 m_convlt = m.m_convlt;
186 m_weight = m.m_weight;
188 m_selectDisplay = m.m_selectDisplay;
189 m_state = m.m_state;
190 m_index_prev = m.m_index_prev;
191 return *this;
192}
193
195{
196 unsigned int range_ = static_cast<unsigned int>(range);
197 // Size of query list includes the point on the line
198 vpMeSite *list_query_pixels = new vpMeSite[(2 * range_) + 1];
199
200 // range : +/- the range within which the pixel's
201 // correspondent will be sought
202
203 double salpha = sin(m_alpha);
204 double calpha = cos(m_alpha);
205 int n = 0;
206 vpImagePoint ip;
207
208 for (int k = -range; k <= range; ++k) {
209 double ii = m_ifloat + (k * salpha);
210 double jj = m_jfloat + (k * calpha);
211
212 // Display
213 if ((m_selectDisplay == RANGE_RESULT) || (m_selectDisplay == RANGE)) {
214 ip.set_i(ii);
215 ip.set_j(jj);
217 }
218
219 // Copy parent's convolution
220 vpMeSite pel;
222 pel.setDisplay(m_selectDisplay); // Display
223
224 // Add site to the query list
225 list_query_pixels[n] = pel;
226 ++n;
227 }
228
229 return list_query_pixels;
230}
231
236unsigned int vpMeSite::computeMaskIndex(const double alpha, const vpMe &me)
237{
238 // Calculate tangent angle from normal
239 double theta = alpha + (M_PI / 2);
240 // Move tangent angle to within 0->M_PI for a positive
241 // mask index
242 while (theta < 0) {
243 theta += M_PI;
244 }
245 while (theta > M_PI) {
246 theta -= M_PI;
247 }
248 // Convert radians to degrees
249 int theta_deg = vpMath::round(vpMath::deg(theta));
250
251 const int flatAngle = 180;
252 if (abs(theta_deg) == flatAngle) {
253 theta_deg = 0;
254 }
255 unsigned int mask_index = static_cast<unsigned int>(theta_deg / static_cast<double>(me.getAngleStep()));
256 return(mask_index);
257}
258
260{
261 int half;
262 int height_ = static_cast<int>(I.getHeight());
263 int width_ = static_cast<int>(I.getWidth());
264
265 double conv = 0.0;
266 unsigned int msize = me->getMaskSize();
267 half = static_cast<int>((msize - 1) >> 1);
268
269 if (outsideImage(m_i, m_j, half + me->getStrip(), height_, width_)) {
270 conv = 0.0;
271 m_i = 0;
272 m_j = 0;
273 }
274 else {
275 unsigned int mask_index = computeMaskIndex(m_alpha, *me);
276
277 unsigned int i_ = static_cast<unsigned int>(m_i);
278 unsigned int j_ = static_cast<unsigned int>(m_j);
279 unsigned int half_ = static_cast<unsigned int>(half);
280
281 unsigned int ihalf = i_ - half_;
282 unsigned int jhalf = j_ - half_;
283
284 for (unsigned int a = 0; a < msize; ++a) {
285 unsigned int ihalfa = ihalf + a;
286 for (unsigned int b = 0; b < msize; ++b) {
287 conv += m_mask_sign * me->getMask()[mask_index][a][b] * I(ihalfa, jhalf + b);
288 }
289 }
290 }
291 return conv;
292}
293
297double vpMeSite::convolution(const vpImage<unsigned char> &I, const vpMe &me, const unsigned int mask_index)
298{
299 int half;
300 int height = static_cast<int>(I.getHeight());
301 int width = static_cast<int>(I.getWidth());
302
303 double conv = 0.0;
304 unsigned int msize = me.getMaskSize();
305 half = static_cast<int>((msize - 1) >> 1);
306
307 if (outsideImage(m_i, m_j, half + me.getStrip(), height, width)) {
308 conv = 0.0;
309 m_i = 0;
310 m_j = 0;
311 }
312 else {
313 unsigned int i_ = static_cast<unsigned int>(m_i);
314 unsigned int j_ = static_cast<unsigned int>(m_j);
315 unsigned int half_ = static_cast<unsigned int>(half);
316
317 unsigned int ihalf = i_ - half_;
318 unsigned int jhalf = j_ - half_;
319
320 for (unsigned int a = 0; a < msize; ++a) {
321 unsigned int ihalfa = ihalf + a;
322 for (unsigned int b = 0; b < msize; ++b) {
323 conv += m_mask_sign * me.getMask()[mask_index][a][b] * I(ihalfa, jhalf + b);
324 }
325 }
326 }
327 return conv;
328}
329
330void vpMeSite::track(const vpImage<unsigned char> &I, const vpMe *me, const bool &test_contrast)
331{
332 int max_rank = -1;
333 double max_convolution = 0;
334 double max = 0;
335 double contrast = 0;
336
337 // range = +/- range of pixels within which the correspondent
338 // of the current pixel will be sought
339 unsigned int range = me->getRange();
340 const unsigned int normalSides = 2;
341 const unsigned int numQueries = range * normalSides + 1;
342 unsigned int mask_index = computeMaskIndex(m_alpha, *me);
343 vpMeSite *list_query_pixels = getQueryList(I, static_cast<int>(range));
344
345 double contrast_max = 1 + me->getMu2();
346 double contrast_min = 1 - me->getMu1();
347
348 double threshold = computeFinalThreshold(*me);
349
350 if (test_contrast) { // likelihood test
351 double diff = 1e6;
352 // Change of mask sign to have a continuity at 0 and 180.
353 // Threshold at 120 to be more than the 90 initial value
354 if (vpMath::abs(static_cast<int>(mask_index - m_index_prev)) > 120) {
356 }
357 for (unsigned int n = 0; n < numQueries; ++n) {
358 // Convolution results
359 list_query_pixels[n].m_mask_sign = m_mask_sign;
360 double convolution_ = list_query_pixels[n].convolution(I, *me, mask_index);
361 // no fabs since m_convlt > 0 and we look for a similar one
362 const double likelihood = convolution_ + m_convlt;
363
364 if (likelihood > threshold) {
365 contrast = convolution_ / m_convlt;
366 if ((contrast > contrast_min) && (contrast < contrast_max) && (fabs(1 - contrast) < diff)) {
367 diff = fabs(1 - contrast);
368 max_convolution = convolution_;
369 max = likelihood;
370 max_rank = static_cast<int>(n);
371 }
372 }
373 }
374 }
375 else { // test on contrast only
376 for (unsigned int n = 0; n < numQueries; ++n) {
377 // Convolution results
378 double convolution_ = list_query_pixels[n].convolution(I, me);
379 const double likelihood = fabs(2 * convolution_);
380 if ((likelihood > max) && (likelihood > threshold)) {
381 max_convolution = convolution_;
382 max = likelihood;
383 max_rank = static_cast<int>(n);
384 }
385 }
386 // in case max_convolution < 0, change of mask sign so that m_convlt > 0
387 // for the future likelihood tests
388 if (max_convolution < 0) {
389 max_convolution = -max_convolution;
391 }
392 }
393
394 vpImagePoint ip;
395
396 if (max_rank >= 0) {
397 if ((m_selectDisplay == RANGE_RESULT) || (m_selectDisplay == RESULT)) {
398 ip.set_i(list_query_pixels[max_rank].m_i);
399 ip.set_j(list_query_pixels[max_rank].m_j);
401 }
402
403 list_query_pixels[max_rank].m_mask_sign = m_mask_sign;
404 list_query_pixels[max_rank].m_index_prev = mask_index;
405 list_query_pixels[max_rank].m_convlt = max_convolution;
406 list_query_pixels[max_rank].m_normGradient = vpMath::sqr(max_convolution);
407
408 *this = list_query_pixels[max_rank]; // The vpMeSite2 is replaced by the vpMeSite2 of max likelihood
409 }
410 else // none of the query sites is better than the threshold
411 {
412 if ((m_selectDisplay == RANGE_RESULT) || (m_selectDisplay == RESULT)) {
413 ip.set_i(list_query_pixels[0].m_i);
414 ip.set_j(list_query_pixels[0].m_j);
416 }
417 m_normGradient = 0;
418 if (std::fabs(contrast) > std::numeric_limits<double>::epsilon()) {
419 m_state = CONTRAST; // contrast suppression
420 }
421 else {
422 m_state = THRESHOLD; // threshold suppression
423 }
424
425 }
426 delete[] list_query_pixels;
427}
428
429void vpMeSite::trackMultipleHypotheses(const vpImage<unsigned char> &I, const vpMe &me, const bool &test_contrast,
430 std::vector<vpMeSite> &outputHypotheses, const unsigned numCandidates)
431{
432 // range = +/- range of pixels within which the correspondent
433 // of the current pixel will be sought
434 unsigned int range = me.getRange();
435 const unsigned int normalSides = 2;
436 const unsigned int numQueries = range * normalSides + 1;
437 unsigned int mask_index = computeMaskIndex(m_alpha, me);
438
439 if (numCandidates > numQueries) {
440 throw vpException(vpException::badValue, "Error in vpMeSite::track(): the number of retained hypotheses cannot be greater to the number of queried sites.");
441 }
442
443 vpMeSite *list_query_pixels = getQueryList(I, static_cast<int>(range));
444
445 // Insert into a map, where the key is the sorting criterion (negative likelihood or contrast diff)
446 // and the key is the ME site + its computed likelihood and contrast.
447 // After computation: iterating on the map is guaranteed to be done with the keys being sorted according to the criterion.
448 // Multimap allows to have multiple values (sites) with the same key (likelihood/contrast diff)
449 // Only the candidates that are above the threshold are kept
450 std::multimap<double, vpMeSiteHypothesis> candidates;
451
452 const double contrast_max = 1 + me.getMu2();
453 const double contrast_min = 1 - me.getMu1();
454
455 const double threshold = computeFinalThreshold(me);
456
457 // First step: compute likelihoods and contrasts for all queries
458 if (test_contrast) {
459 // Change of mask sign to have a continuity at 0 and 180.
460 // Threshold at 120 to be more than the 90 initial value
461 if (vpMath::abs(static_cast<int>(mask_index - m_index_prev)) > 120) {
463 }
464 for (unsigned int n = 0; n < numQueries; ++n) {
465 // Convolution results
466 list_query_pixels[n].m_mask_sign = m_mask_sign;
467 vpMeSite &query = list_query_pixels[n];
468 // Convolution results
469 const double convolution_ = query.convolution(I, me, mask_index);
470 // no fabs since m_convlt > 0 and we look for a similar one
471 const double likelihood = convolution_ + m_convlt;
472
473 query.m_convlt = convolution_;
474 const double contrast = convolution_ / m_convlt;
475 candidates.insert(std::pair<double, vpMeSiteHypothesis>(fabs(1.0 - contrast), vpMeSiteHypothesis(&query, likelihood, contrast)));
476 }
477 }
478 else { // test on likelihood only
479 for (unsigned int n = 0; n < numQueries; ++n) {
480 // convolution results
481 vpMeSite &query = list_query_pixels[n];
482 const double convolution_ = query.convolution(I, &me);
483 const double likelihood = fabs(2 * convolution_);
484 query.m_convlt = convolution_;
485 candidates.insert(std::pair<double, vpMeSiteHypothesis>(-likelihood, vpMeSiteHypothesis(&query, likelihood, 0.0)));
486 }
487 }
488 // Take first numCandidates hypotheses: map is sorted according to the likelihood/contrast difference so we can just
489 // iterate from the start
490 outputHypotheses.resize(numCandidates);
491
492 std::multimap<double, vpMeSiteHypothesis>::iterator it = candidates.begin();
493 if (test_contrast) {
494 for (unsigned int i = 0; i < numCandidates; ++i, ++it) {
495 outputHypotheses[i] = *(it->second.site);
496 outputHypotheses[i].m_normGradient = vpMath::sqr(outputHypotheses[i].m_convlt);
497 const double likelihood = it->second.likelihood;
498 const double contrast = it->second.contrast;
499
500 if (likelihood > threshold) {
501 if (contrast <= contrast_min || contrast >= contrast_max) {
502 outputHypotheses[i].m_state = CONTRAST;
503 }
504 else {
505 outputHypotheses[i].m_state = NO_SUPPRESSION;
506 }
507 }
508 else {
509 outputHypotheses[i].m_state = THRESHOLD;
510 }
511 }
512 }
513 else {
514 for (unsigned int i = 0; i < numCandidates; ++i, ++it) {
515 outputHypotheses[i] = *(it->second.site);
516 const double likelihood = it->second.likelihood;
517 if (likelihood > threshold) {
518 outputHypotheses[i].m_state = NO_SUPPRESSION;
519 }
520 else {
521 outputHypotheses[i].m_state = THRESHOLD;
522 }
523 }
524 }
525
526 const vpMeSite &bestMatch = outputHypotheses[0];
527
528 if (bestMatch.m_state != NO_SUPPRESSION) {
529 if ((m_selectDisplay == RANGE_RESULT) || (m_selectDisplay == RESULT)) {
530
531 vpDisplay::displayPoint(I, bestMatch.m_i, bestMatch.m_j, vpColor::red);
532 }
533 *this = outputHypotheses[0];
534 }
535 else {
536 if ((m_selectDisplay == RANGE_RESULT) || (m_selectDisplay == RESULT)) {
537 vpDisplay::displayPoint(I, bestMatch.m_i, bestMatch.m_j, vpColor::green);
538 }
539 m_normGradient = 0;
540 }
541
542 delete[] list_query_pixels;
543}
544
545int vpMeSite::operator!=(const vpMeSite &m) { return ((m.m_i != m_i) || (m.m_j != m_j)); }
546
548
550
551// Static functions
552
553void vpMeSite::display(const vpImage<unsigned char> &I, const double &i, const double &j, const vpMeSiteState &state)
554{
555 const unsigned int crossSize = 3;
556 switch (state) {
557 case NO_SUPPRESSION:
558 vpDisplay::displayCross(I, vpImagePoint(i, j), crossSize, vpColor::green, 1);
559 break;
560
561 case CONTRAST:
562 vpDisplay::displayCross(I, vpImagePoint(i, j), crossSize, vpColor::blue, 1);
563 break;
564
565 case THRESHOLD:
567 break;
568
569 case M_ESTIMATOR:
570 vpDisplay::displayCross(I, vpImagePoint(i, j), crossSize, vpColor::red, 1);
571 break;
572
573 case OUTSIDE_ROI_MASK:
574 vpDisplay::displayCross(I, vpImagePoint(i, j), crossSize, vpColor::cyan, 1);
575 break;
576
577 default:
579 }
580}
581
582void vpMeSite::display(const vpImage<vpRGBa> &I, const double &i, const double &j, const vpMeSiteState &state)
583{
584 const unsigned int cross_size = 3;
585 switch (state) {
586 case NO_SUPPRESSION:
587 vpDisplay::displayCross(I, vpImagePoint(i, j), cross_size, vpColor::green, 1);
588 break;
589
590 case CONTRAST:
591 vpDisplay::displayCross(I, vpImagePoint(i, j), cross_size, vpColor::blue, 1);
592 break;
593
594 case THRESHOLD:
595 vpDisplay::displayCross(I, vpImagePoint(i, j), cross_size, vpColor::purple, 1);
596 break;
597
598 case M_ESTIMATOR:
599 vpDisplay::displayCross(I, vpImagePoint(i, j), cross_size, vpColor::red, 1);
600 break;
601
602 case OUTSIDE_ROI_MASK:
603 vpDisplay::displayCross(I, vpImagePoint(i, j), cross_size, vpColor::cyan, 1);
604 break;
605
606 default:
607 vpDisplay::displayCross(I, vpImagePoint(i, j), cross_size, vpColor::yellow, 1);
608 }
609}
610
611VISP_EXPORT std::ostream &operator<<(std::ostream &os, vpMeSite &me_site)
612{
613 return (os << "Alpha: " << me_site.m_alpha << " Convolution: " << me_site.m_convlt << " Weight: " << me_site.m_weight << " Threshold: " << me_site.m_contrastThreshold);
614}
615
616END_VISP_NAMESPACE
static const vpColor red
Definition vpColor.h:198
static const vpColor cyan
Definition vpColor.h:207
static const vpColor blue
Definition vpColor.h:204
static const vpColor purple
Definition vpColor.h:209
static const vpColor yellow
Definition vpColor.h:206
static const vpColor green
Definition vpColor.h:201
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_j(double jj)
void set_i(double ii)
Definition of the vpImage class member functions.
Definition vpImage.h:131
static double sqr(double x)
Definition vpMath.h:203
static Type abs(const Type &x)
Definition vpMath.h:272
static int round(double x)
Definition vpMath.h:413
static double deg(double rad)
Definition vpMath.h:119
int m_mask_sign
Mask sign.
Definition vpMeSite.h:114
vpMeSiteState
Definition vpMeSite.h:92
@ OUTSIDE_ROI_MASK
Point is outside the region of interest mask, but retained in the ME list.
Definition vpMeSite.h:102
@ THRESHOLD
Point not tracked due to the likelihood that is below the threshold, but retained in the ME list.
Definition vpMeSite.h:98
@ CONTRAST
Point not tracked due to a contrast problem, but retained in the ME list.
Definition vpMeSite.h:94
@ M_ESTIMATOR
Point detected as an outlier during virtual visual-servoing.
Definition vpMeSite.h:99
@ NO_SUPPRESSION
Point successfully tracked.
Definition vpMeSite.h:93
void setDisplay(vpMeSiteDisplayType select)
Definition vpMeSite.h:287
int operator!=(const vpMeSite &m)
Definition vpMeSite.cpp:545
friend VISP_EXPORT std::ostream & operator<<(std::ostream &os, vpMeSite &vpMeS)
Definition vpMeSite.cpp:611
double m_ifloat
Subpixel coordinates along i of a site.
Definition vpMeSite.h:110
vpMeSite * getQueryList(const vpImage< unsigned char > &I, const int &range) const
Definition vpMeSite.cpp:194
double m_normGradient
Convolution of Site in previous image.
Definition vpMeSite.h:120
unsigned int computeMaskIndex(const double alpha, const vpMe &me)
Definition vpMeSite.cpp:236
void display(const vpImage< unsigned char > &I) const
Definition vpMeSite.cpp:547
double convolution(const vpImage< unsigned char > &ima, const vpMe *me)
Definition vpMeSite.cpp:259
void init()
Definition vpMeSite.cpp:70
double m_convlt
Convolution of Site in previous image.
Definition vpMeSite.h:118
double m_alpha
Angle of tangent at site.
Definition vpMeSite.h:116
@ NONE
Not displayed.
Definition vpMeSite.h:82
@ RANGE_RESULT
Definition vpMeSite.h:85
vpMeSite & operator=(const vpMeSite &m)
Definition vpMeSite.cpp:176
void trackMultipleHypotheses(const vpImage< unsigned char > &I, const vpMe &me, const bool &test_contrast, std::vector< vpMeSite > &outputHypotheses, const unsigned numCandidates)
Definition vpMeSite.cpp:429
double computeFinalThreshold(const vpMe &me) const
Definition vpMeSite.h:352
double m_contrastThreshold
Old likelihood ratio threshold (to be avoided) or easy-to-use normalized threshold: minimal contrast.
Definition vpMeSite.h:124
int m_j
Integer coordinates along j of a site.
Definition vpMeSite.h:108
int m_i
Integer coordinate along i of a site.
Definition vpMeSite.h:106
double m_jfloat
Subpixel coordinates along j of a site.
Definition vpMeSite.h:112
double m_weight
Uncertainty of point given as a probability between 0 and 1.
Definition vpMeSite.h:122
void track(const vpImage< unsigned char > &I, const vpMe *me, const bool &test_contrast=true)
Definition vpMeSite.cpp:330
Definition vpMe.h:143
unsigned int getAngleStep() const
Definition vpMe.h:202
vpMatrix * getMask() const
Definition vpMe.h:215
double getMu1() const
Definition vpMe.h:255
int getStrip() const
Definition vpMe.h:297
double getMu2() const
Definition vpMe.h:262
unsigned int getMaskSize() const
Definition vpMe.h:240
unsigned int getRange() const
Definition vpMe.h:283