40 #include <visp3/core/vpColVector.h>
41 #include <visp3/core/vpMath.h>
42 #include <visp3/me/vpMe.h>
44 #ifndef DOXYGEN_SHOULD_SKIP_THIS
60 template <
class Type>
inline void permute(Type &a, Type &b)
67 static vpDroite2Dt droiteCartesienne(vpPoint2Dt P, vpPoint2Dt Q)
73 PQ.c = (Q.y * P.x) - (Q.x * P.y);
78 static vpPoint2Dt pointIntersection(vpDroite2Dt D1, vpDroite2Dt D2)
83 det = ((D1.a * D2.b) - (D2.a * D1.b));
84 I.x = ((D2.c * D1.b) - (D1.c * D2.b)) / det;
85 I.y = ((D1.c * D2.a) - (D2.c * D1.a)) / det;
90 static void recale(vpPoint2Dt &P,
double Xmin,
double Ymin,
double Xmax,
double Ymax)
109 static void permute(vpPoint2Dt &A, vpPoint2Dt &B)
122 static bool clipping(vpPoint2Dt A, vpPoint2Dt B,
double Xmin,
double Ymin,
double Xmax,
double Ymax, vpPoint2Dt &Ac,
125 vpDroite2Dt AB, D[4];
143 unsigned int code_P[nbP],
147 AB = droiteCartesienne(A, B);
153 for (n = 0; n < nbP; ++n) {
175 if ((code_P[0] | code_P[1]) == 0) {
186 if ((code_P[0] & code_P[1]) != 0)
195 if (code_P[0] != 0) {
198 for (i = 0; !(code_P[0] & bit_i); ++i) {
205 for (i = 0; !(code_P[1] & bit_i); ++i) {
210 P[n] = pointIntersection(AB, D[i]);
215 recale(P[n], Xmin, Ymin, Xmax, Ymax);
222 static double surfaceRelative(vpPoint2Dt P, vpPoint2Dt Q,
double Xmin,
double Ymin,
double Xmax,
double Ymax)
229 recale(P, Xmin, Ymin, Xmax, Ymax);
230 recale(Q, Xmin, Ymin, Xmax, Ymax);
233 if ((std::fabs(P.x - Xmin) <=
234 (
vpMath::maximum(std::fabs(P.x), std::fabs(Xmin)) * std::numeric_limits<double>::epsilon())) &&
235 (std::fabs(Q.x - Xmax) <=
236 (
vpMath::maximum(std::fabs(Q.x), std::fabs(Xmax)) * std::numeric_limits<double>::epsilon()))) {
237 return fabs((Ymax + Ymin) - (P.y - Q.y));
241 if (((std::fabs(P.y - Ymin) <=
242 (
vpMath::maximum(std::fabs(P.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon())) &&
243 (std::fabs(Q.y - Ymax) <=
244 (
vpMath::maximum(std::fabs(Q.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon()))) ||
245 ((std::fabs(Q.y - Ymin) <=
246 (
vpMath::maximum(std::fabs(Q.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon())) &&
247 (std::fabs(P.y - Ymax) <=
248 (
vpMath::maximum(std::fabs(P.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon())))) {
249 return fabs((Xmax + Xmin) - (P.x - Q.x));
253 if ((std::fabs(P.x - Xmin) <=
254 (
vpMath::maximum(std::fabs(P.x), std::fabs(Xmin)) * std::numeric_limits<double>::epsilon())) &&
255 (std::fabs(Q.y - Ymax) <=
256 (
vpMath::maximum(std::fabs(Q.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon()))) {
257 return (1 - ((Ymax - P.y) * (Q.x - Xmin)));
261 if ((std::fabs(P.x - Xmin) <=
262 (
vpMath::maximum(std::fabs(P.x), std::fabs(Xmin)) * std::numeric_limits<double>::epsilon())) &&
263 (std::fabs(Q.y - Ymin) <=
264 (
vpMath::maximum(std::fabs(Q.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon()))) {
265 return (1 - ((P.y - Ymin) * (Q.x - Xmin)));
269 if ((std::fabs(P.y - Ymin) <=
270 (
vpMath::maximum(std::fabs(P.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon())) &&
271 (std::fabs(Q.x - Xmax) <=
272 (
vpMath::maximum(std::fabs(Q.x), std::fabs(Xmax)) * std::numeric_limits<double>::epsilon()))) {
273 return (1 - ((Xmax - P.x) * (Q.y - Ymin)));
277 if ((std::fabs(P.y - Ymax) <=
278 (
vpMath::maximum(std::fabs(P.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon())) &&
279 (std::fabs(Q.x - Xmax) <=
280 (
vpMath::maximum(std::fabs(Q.x), std::fabs(Xmax)) * std::numeric_limits<double>::epsilon()))) {
281 return (1 - ((Xmax - P.x) * (Ymax - Q.y)));
284 throw(
vpException(
vpException::fatalError,
"utils_ecm: error in surfaceRelative (%f,%f) (%f,%f) %f %f %f %f", P.x, P.y, Q.x, Q.y, Xmin, Ymin, Xmax, Ymax));
292 double X, Y, moitie = (
static_cast<double>(n)) / 2.0;
293 vpPoint2Dt P1, Q1, P, Q;
298 double norm = 1.0 / (n * trunc(n / 2.0));
300 unsigned int nb_theta = angle.
getRows();
302 for (
unsigned int i_theta = 0; i_theta < nb_theta; ++i_theta) {
303 double theta = (M_PI / 180) * angle[i_theta];
305 double cos_theta = cos(theta);
306 double sin_theta = sin(theta);
311 const double thetaWhoseTanInfinite = 90.;
312 if (std::fabs(angle[i_theta] - thetaWhoseTanInfinite) <= (
vpMath::maximum(std::fabs(angle[i_theta]), thetaWhoseTanInfinite) *
313 std::numeric_limits<double>::epsilon()))
316 P1.y = -
static_cast<int>(n);
321 double tan_theta = sin_theta / cos_theta;
322 P1.x = -
static_cast<int>(n);
323 P1.y = tan_theta * (-
static_cast<int>(n));
325 Q1.y = tan_theta * n;
332 for (i = 0, Y = (-moitie + 0.5); i < n; ++i, ++Y) {
333 for (j = 0, X = (-moitie + 0.5); j < n; ++j, ++X) {
335 int sgn =
vpMath::sign((cos_theta * Y) - (sin_theta * X));
338 if (clipping(P1, Q1, X - 0.5, Y - 0.5, X + 0.5, Y + 0.5, P, Q)) {
340 v = surfaceRelative(P, Q, X - 0.5, Y - 0.5, X + 0.5, Y + 0.5);
346 M[i_theta][i][j] = sgn * v * norm;
356 if (m_mask !=
nullptr) {
360 m_mask =
new vpMatrix[m_mask_number];
364 unsigned int angle_pas = 180 / m_mask_number;
367 for (
unsigned int k = 0; k < m_mask_number; ++k) {
372 calculMasques(angle, m_mask_size, m_mask);
377 std::cout << std::endl;
378 std::cout <<
"Moving edges settings " << std::endl;
379 std::cout << std::endl;
380 std::cout <<
" Size of the convolution masks...." << m_mask_size <<
"x" << m_mask_size <<
" pixels" << std::endl;
381 std::cout <<
" Number of masks.................." << m_mask_number << std::endl;
382 std::cout <<
" Query range +/- J................" << m_range <<
" pixels" << std::endl;
383 std::cout <<
" Likelihood threshold type........" << (m_likelihood_threshold_type ==
NORMALIZED_THRESHOLD ?
"normalized " :
"old threshold (to be avoided)") << std::endl;
385 if (m_useAutomaticThreshold) {
386 std::cout <<
" Likelihood threshold............." <<
"unused" << std::endl;
387 std::cout <<
" Likelihood margin ratio.........." << m_thresholdMarginRatio << std::endl;
388 std::cout <<
" Minimum likelihood threshold....." << m_minThreshold << std::endl;
391 std::cout <<
" Likelihood threshold............." << m_threshold << std::endl;
392 std::cout <<
" Likelihood margin ratio.........." <<
"unused" << std::endl;
393 std::cout <<
" Minimum likelihood threshold....." <<
"unused" << std::endl;
396 std::cout <<
" Contrast tolerance +/-..........." << m_mu1 * 100 <<
"% and " << m_mu2 * 100 <<
"% " << std::endl;
397 std::cout <<
" Sample step......................" << m_sample_step <<
" pixels" << std::endl;
398 std::cout <<
" Strip............................" << m_strip <<
" pixels " << std::endl;
399 std::cout <<
" Min sample step.................." << m_min_samplestep <<
" pixels " << std::endl;
403 : m_likelihood_threshold_type(OLD_THRESHOLD), m_threshold(10000), m_thresholdMarginRatio(-1), m_minThreshold(-1), m_useAutomaticThreshold(false),
404 m_mu1(0.5), m_mu2(0.5), m_min_samplestep(4), m_anglestep(1), m_mask_sign(0), m_range(4), m_sample_step(10),
405 m_ntotal_sample(0), m_points_to_track(500), m_mask_size(5), m_mask_number(180), m_strip(2), m_mask(nullptr)
407 const unsigned int flatAngle = 180;
408 m_anglestep = (flatAngle / m_mask_number);
414 : m_likelihood_threshold_type(OLD_THRESHOLD), m_threshold(10000), m_thresholdMarginRatio(-1), m_minThreshold(-1), m_useAutomaticThreshold(false),
415 m_mu1(0.5), m_mu2(0.5), m_min_samplestep(4), m_anglestep(1), m_mask_sign(0), m_range(4), m_sample_step(10),
416 m_ntotal_sample(0), m_points_to_track(500), m_mask_size(5), m_mask_number(180), m_strip(2), m_mask(nullptr)
423 if (m_mask !=
nullptr) {
428 m_likelihood_threshold_type = me.m_likelihood_threshold_type;
429 m_threshold = me.m_threshold;
430 m_thresholdMarginRatio = me.m_thresholdMarginRatio;
431 m_minThreshold = me.m_minThreshold;
432 m_useAutomaticThreshold = me.m_useAutomaticThreshold;
435 m_min_samplestep = me.m_min_samplestep;
436 m_anglestep = me.m_anglestep;
437 m_mask_size = me.m_mask_size;
438 m_mask_number = me.m_mask_number;
439 m_mask_sign = me.m_mask_sign;
440 m_range = me.m_range;
441 m_sample_step = me.m_sample_step;
442 m_ntotal_sample = me.m_ntotal_sample;
443 m_points_to_track = me.m_points_to_track;
444 m_strip = me.m_strip;
450 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
453 if (m_mask !=
nullptr) {
457 m_likelihood_threshold_type = std::move(me.m_likelihood_threshold_type);
458 m_threshold = std::move(me.m_threshold);
459 m_thresholdMarginRatio = std::move(me.m_thresholdMarginRatio);
460 m_minThreshold = std::move(me.m_minThreshold);
461 m_useAutomaticThreshold = std::move(me.m_useAutomaticThreshold);
462 m_mu1 = std::move(me.m_mu1);
463 m_mu2 = std::move(me.m_mu2);
464 m_min_samplestep = std::move(me.m_min_samplestep);
465 m_anglestep = std::move(me.m_anglestep);
466 m_mask_size = std::move(me.m_mask_size);
467 m_mask_number = std::move(me.m_mask_number);
468 m_mask_sign = std::move(me.m_mask_sign);
469 m_range = std::move(me.m_range);
470 m_sample_step = std::move(me.m_sample_step);
471 m_ntotal_sample = std::move(me.m_ntotal_sample);
472 m_points_to_track = std::move(me.m_points_to_track);
473 m_strip = std::move(me.m_strip);
482 if (m_mask !=
nullptr) {
490 const unsigned int flatAngle = 180;
491 m_mask_number = mask_number;
492 m_anglestep = flatAngle / m_mask_number;
498 m_mask_size = mask_size;
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int getRows() const
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
static Type maximum(const Type &a, const Type &b)
static bool equal(double x, double y, double threshold=0.001)
static int sign(double x)
Implementation of a matrix and operations on matrices.
void setMaskNumber(const unsigned int &mask_number)
void setMaskSize(const unsigned int &mask_size)
vpMe & operator=(const vpMe &me)