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;
338 unsigned int angle_pas;
342 for (
unsigned int i = 0; k <
n_mask; i += angle_pas)
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...." <<
mask_size <<
"x" <<
mask_size <<
" pixels" << std::endl;
354 std::cout <<
" Number of masks.................." <<
n_mask << std::endl;
355 std::cout <<
" Query range +/- J................" <<
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............." <<
threshold << std::endl;
358 std::cout <<
" Contrast tolerance +/-..........." <<
mu1 * 100 <<
"% and " <<
mu2 * 100 <<
"% " << std::endl;
359 std::cout <<
" Sample step......................" <<
sample_step <<
" pixels" << std::endl;
360 std::cout <<
" Strip............................" <<
strip <<
" pixels " << std::endl;
361 std::cout <<
" Min sample step.................." <<
min_samplestep <<
" pixels " << std::endl;
365 : m_likelihood_threshold_type(OLD_THRESHOLD), threshold(10000),
366 mu1(0.5), mu2(0.5), min_samplestep(4), anglestep(1), mask_sign(0), range(4), sample_step(10),
367 ntotal_sample(0), points_to_track(500), mask_size(5), n_mask(180), strip(2), mask(NULL)
377 : m_likelihood_threshold_type(OLD_THRESHOLD), threshold(10000),
378 mu1(0.5), mu2(0.5), min_samplestep(4), anglestep(1), mask_sign(0), range(4), sample_step(10),
379 ntotal_sample(0), points_to_track(500), mask_size(5), n_mask(180), strip(2), mask(NULL)
391 m_likelihood_threshold_type = me.m_likelihood_threshold_type;
410 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
417 m_likelihood_threshold_type = std::move(me.m_likelihood_threshold_type);
419 mu1 = std::move(me.mu1);
420 mu2 = std::move(me.mu2);
424 n_mask = std::move(me.n_mask);
426 range = std::move(me.range);
430 strip = std::move(me.strip);
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.
int ntotal_sample
Distance between sampled points in pixels.
double sample_step
Seek range - on both sides of the reference pixel.
double min_samplestep
Contrast continuity parameter (right boundary)
void setMaskSize(const unsigned int &a)
double mu1
Old likelihood ratio threshold (to be avoided) or easy-to-use normalized threshold: minimal contrast.
vpMe()
Array of matrices defining the different masks (one for every angle step).
double mu2
Contrast continuity parameter (left boundary)
vpMe & operator=(const vpMe &me)
@ NORMALIZED_THRESHOLD
Easy-to-use normalized likelihood threshold corresponding to the minimal luminance contrast to consid...
void setMaskNumber(const unsigned int &a)