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 vpDroite2D_t droite_cartesienne(vpPoint2D_t P, vpPoint2D_t Q)
73 PQ.c = Q.y * P.x - Q.x * P.y;
78 static vpPoint2D_t point_intersection(vpDroite2D_t D1, vpDroite2D_t 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(vpPoint2D_t &P,
double Xmin,
double Ymin,
double Xmax,
double Ymax)
103 static void permute(vpPoint2D_t &A, vpPoint2D_t &B)
116 static bool clipping(vpPoint2D_t A, vpPoint2D_t B,
double Xmin,
double Ymin,
double Xmax,
double Ymax, vpPoint2D_t &Ac,
119 vpDroite2D_t AB, D[4];
140 AB = droite_cartesienne(A, B);
146 for (n = 0; n < 2; n++) {
161 if ((code_P[0] | code_P[1]) == 0000)
176 if ((code_P[0] & code_P[1]) != 0000)
185 if (code_P[0] != 0000) {
187 for (i = 0, bit_i = 1; !(code_P[0] & bit_i); i++, bit_i <<= 1) {
192 for (i = 0, bit_i = 1; !(code_P[1] & bit_i); i++, bit_i <<= 1) {
196 P[n] = point_intersection(AB, D[i]);
201 recale(P[n], Xmin, Ymin, Xmax, Ymax);
208 static double S_relative(vpPoint2D_t P, vpPoint2D_t Q,
double Xmin,
double Ymin,
double Xmax,
double Ymax)
214 recale(P, Xmin, Ymin, Xmax, Ymax);
215 recale(Q, Xmin, Ymin, Xmax, Ymax);
218 if ((std::fabs(P.x - Xmin) <=
219 vpMath::maximum(std::fabs(P.x), std::fabs(Xmin)) * std::numeric_limits<double>::epsilon()) &&
220 (std::fabs(Q.x - Xmax) <=
221 vpMath::maximum(std::fabs(Q.x), std::fabs(Xmax)) * std::numeric_limits<double>::epsilon()))
222 return (fabs(Ymax + Ymin - P.y - Q.y));
226 if (((std::fabs(P.y - Ymin) <=
227 vpMath::maximum(std::fabs(P.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon()) &&
228 (std::fabs(Q.y - Ymax) <=
229 vpMath::maximum(std::fabs(Q.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon())) ||
230 ((std::fabs(Q.y - Ymin) <=
231 vpMath::maximum(std::fabs(Q.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon()) &&
232 (std::fabs(P.y - Ymax) <=
233 vpMath::maximum(std::fabs(P.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon())))
234 return (fabs(Xmax + Xmin - P.x - Q.x));
237 if (std::fabs(P.x - Xmin) <=
238 vpMath::maximum(std::fabs(P.x), std::fabs(Xmin)) * std::numeric_limits<double>::epsilon() &&
239 std::fabs(Q.y - Ymax) <=
240 vpMath::maximum(std::fabs(Q.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon())
241 return (1 - (Ymax - P.y) * (Q.x - Xmin));
243 if (std::fabs(P.x - Xmin) <=
244 vpMath::maximum(std::fabs(P.x), std::fabs(Xmin)) * 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 return (1 - (P.y - Ymin) * (Q.x - Xmin));
249 if (std::fabs(P.y - Ymin) <=
250 vpMath::maximum(std::fabs(P.y), std::fabs(Ymin)) * std::numeric_limits<double>::epsilon() &&
251 std::fabs(Q.x - Xmax) <=
252 vpMath::maximum(std::fabs(Q.x), std::fabs(Xmax)) * std::numeric_limits<double>::epsilon())
253 return (1 - (Xmax - P.x) * (Q.y - Ymin));
255 if (std::fabs(P.y - Ymax) <=
256 vpMath::maximum(std::fabs(P.y), std::fabs(Ymax)) * std::numeric_limits<double>::epsilon() &&
257 std::fabs(Q.x - Xmax) <=
258 vpMath::maximum(std::fabs(Q.x), std::fabs(Xmax)) * std::numeric_limits<double>::epsilon())
259 return (1 - (Xmax - P.x) * (Ymax - Q.y));
261 throw(
vpException(
vpException::fatalError,
"utils_ecm: error in S_relative (%f,%f) (%f,%f) %f %f %f %f", P.x, P.y, Q.x, Q.y, Xmin, Ymin, Xmax, Ymax));
269 double X, Y, moitie = ((double)n) / 2.0;
270 vpPoint2D_t P1, Q1, P, Q;
275 double norm = 1.0 / (n * trunc(n / 2.0));
277 unsigned int nb_theta = angle.
getRows();
279 for (
unsigned int i_theta = 0; i_theta < nb_theta; i_theta++) {
280 double theta = M_PI / 180 * angle[i_theta];
282 double cos_theta = cos(theta);
283 double sin_theta = sin(theta);
288 if (std::fabs(angle[i_theta] - 90) <=
vpMath::maximum(std::fabs(angle[i_theta]), 90.) *
289 std::numeric_limits<double>::epsilon())
297 double tan_theta = sin_theta / cos_theta;
299 P1.y = tan_theta * (-(int)n);
301 Q1.y = tan_theta * n;
308 for (i = 0, Y = -moitie + 0.5; i < n; i++, Y++) {
309 for (j = 0, X = -moitie + 0.5; j < n; j++, X++) {
314 if (clipping(P1, Q1, X - 0.5, Y - 0.5, X + 0.5, Y + 0.5, P, Q)) {
316 v = S_relative(P, Q, X - 0.5, Y - 0.5, X + 0.5, Y + 0.5);
321 M[i_theta][i][j] = sgn * v * norm;
331 if (m_mask !=
nullptr)
334 m_mask =
new vpMatrix[m_mask_number];
338 unsigned int angle_pas;
339 angle_pas = 180 / m_mask_number;
342 for (
unsigned int i = 0; k < m_mask_number; i += angle_pas)
345 calcul_masques(angle, m_mask_size, m_mask);
350 std::cout << std::endl;
351 std::cout <<
"Moving edges settings " << std::endl;
352 std::cout << std::endl;
353 std::cout <<
" Size of the convolution masks...." << m_mask_size <<
"x" << m_mask_size <<
" pixels" << std::endl;
354 std::cout <<
" Number of masks.................." << m_mask_number << std::endl;
355 std::cout <<
" Query range +/- J................" << m_range <<
" pixels" << std::endl;
356 std::cout <<
" Likelihood threshold type........" << (m_likelihood_threshold_type ==
NORMALIZED_THRESHOLD ?
"normalized " :
"old threshold (to be avoided)") << std::endl;
357 std::cout <<
" Likelihood threshold............." << m_threshold << std::endl;
358 std::cout <<
" Contrast tolerance +/-..........." << m_mu1 * 100 <<
"% and " << m_mu2 * 100 <<
"% " << std::endl;
359 std::cout <<
" Sample step......................" << m_sample_step <<
" pixels" << std::endl;
360 std::cout <<
" Strip............................" << m_strip <<
" pixels " << std::endl;
361 std::cout <<
" Min sample step.................." << m_min_samplestep <<
" pixels " << std::endl;
365 : m_likelihood_threshold_type(OLD_THRESHOLD), m_threshold(10000),
366 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),
367 m_ntotal_sample(0), m_points_to_track(500), m_mask_size(5), m_mask_number(180), m_strip(2), m_mask(nullptr)
369 m_anglestep = (180 / m_mask_number);
375 : m_likelihood_threshold_type(OLD_THRESHOLD), m_threshold(10000),
376 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),
377 m_ntotal_sample(0), m_points_to_track(500), m_mask_size(5), m_mask_number(180), m_strip(2), m_mask(nullptr)
384 if (m_mask !=
nullptr) {
389 m_likelihood_threshold_type = me.m_likelihood_threshold_type;
390 m_threshold = me.m_threshold;
393 m_min_samplestep = me.m_min_samplestep;
394 m_anglestep = me.m_anglestep;
395 m_mask_size = me.m_mask_size;
396 m_mask_number = me.m_mask_number;
397 m_mask_sign = me.m_mask_sign;
398 m_range = me.m_range;
399 m_sample_step = me.m_sample_step;
400 m_ntotal_sample = me.m_ntotal_sample;
401 m_points_to_track = me.m_points_to_track;
402 m_strip = me.m_strip;
410 if (m_mask !=
nullptr) {
414 m_likelihood_threshold_type = std::move(me.m_likelihood_threshold_type);
415 m_threshold = std::move(me.m_threshold);
416 m_mu1 = std::move(me.m_mu1);
417 m_mu2 = std::move(me.m_mu2);
418 m_min_samplestep = std::move(me.m_min_samplestep);
419 m_anglestep = std::move(me.m_anglestep);
420 m_mask_size = std::move(me.m_mask_size);
421 m_mask_number = std::move(me.m_mask_number);
422 m_mask_sign = std::move(me.m_mask_sign);
423 m_range = std::move(me.m_range);
424 m_sample_step = std::move(me.m_sample_step);
425 m_ntotal_sample = std::move(me.m_ntotal_sample);
426 m_points_to_track = std::move(me.m_points_to_track);
427 m_strip = std::move(me.m_strip);
435 if (m_mask !=
nullptr) {
443 m_mask_number = mask_number;
444 m_anglestep = 180 / m_mask_number;
450 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)