From 3bafa851e6f511906f2d498a839b98b18521dfdc Mon Sep 17 00:00:00 2001 From: Fabien Spindler Date: Fri, 2 Feb 2024 16:44:53 +0100 Subject: [PATCH] Improve vpMeEllipse::initTracking() to be able to retrieve pixels used for initialization when initialized by mouse click --- .../tracker/me/include/visp3/me/vpMeEllipse.h | 43 ++++++++++--- .../me/src/moving-edges/vpMeEllipse.cpp | 61 +++++++++++++++++++ 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/modules/tracker/me/include/visp3/me/vpMeEllipse.h b/modules/tracker/me/include/visp3/me/vpMeEllipse.h index f68b0243a2..343858a274 100644 --- a/modules/tracker/me/include/visp3/me/vpMeEllipse.h +++ b/modules/tracker/me/include/visp3/me/vpMeEllipse.h @@ -229,22 +229,47 @@ class VISP_EXPORT vpMeEllipse : public vpMeTracker void initTracking(const vpImage &I, bool trackCircle = false, bool trackArc = false); /*! - * Initialize the tracking of an ellipse/circle or an arc of an ellipse/circle when \e trackArc is set to true. - * The ellipse/circle is defined thanks to a vector of image points. + * Initialize the tracking of an ellipse or an arc of an ellipse when \e trackArc is set to true. + * If \b ips is set, use the contained points to initialize the ME if there are some, or initialize + * by clicks the ME and \b ips will contained the clicked points. + * If \b ips is not set, call the method vpMeEllispe::initTracking(const vpImage&, bool, bool). + * + * \sa \ref vpMeEllispe::initTracking() * - * \warning It is mandatory to use at least five image points to estimate the - * ellipse parameters while three points are needed to estimate the circle parameters. - * \warning The image points should be selected as far as possible from each other. - * When an arc of an ellipse/circle is tracked, it is recommended to select the 5/3 points clockwise. + * \warning The points should be selected as far as possible from each other. + * When an arc of an ellipse is tracked, it is recommended to select the 5 points clockwise. * - * \param I : Image in which the ellipse/circle appears. - * \param iP : A vector of image points belonging to the ellipse/circle edge used to - * initialize the tracking. + * \param I : Image in which the ellipse appears. + * \param opt_ips: If set, either a vector that contains the vpImagePoint to use or will be filled with the clicked + * points. * \param trackCircle : When true, track a circle, when false track an ellipse. * \param trackArc : When true track an arc of the ellipse/circle. In that case, first and * last points specify the extremities of the arc (clockwise). * When false track the complete ellipse/circle. */ +#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) + void initTracking(const vpImage &I, std::optional> &opt_ips, bool trackCircle = false, bool trackArc = false); +#else + void initTracking(const vpImage &I, std::vector *opt_ips, bool trackCircle = false, bool trackArc = false); +#endif + +/*! + * Initialize the tracking of an ellipse/circle or an arc of an ellipse/circle when \e trackArc is set to true. + * The ellipse/circle is defined thanks to a vector of image points. + * + * \warning It is mandatory to use at least five image points to estimate the + * ellipse parameters while three points are needed to estimate the circle parameters. + * \warning The image points should be selected as far as possible from each other. + * When an arc of an ellipse/circle is tracked, it is recommended to select the 5/3 points clockwise. + * + * \param I : Image in which the ellipse/circle appears. + * \param iP : A vector of image points belonging to the ellipse/circle edge used to + * initialize the tracking. + * \param trackCircle : When true, track a circle, when false track an ellipse. + * \param trackArc : When true track an arc of the ellipse/circle. In that case, first and + * last points specify the extremities of the arc (clockwise). + * When false track the complete ellipse/circle. + */ void initTracking(const vpImage &I, const std::vector &iP, bool trackCircle = false, bool trackArc = false); diff --git a/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp b/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp index 0e2c34c101..664f440e9a 100644 --- a/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp +++ b/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp @@ -1131,6 +1131,67 @@ void vpMeEllipse::initTracking(const vpImage &I, bool trackCircle initTracking(I, iP, trackCircle, trackArc); } +#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) +void vpMeEllipse::initTracking(const vpImage &I, std::optional> &opt_ips, bool trackCircle, bool trackArc) +#else +void vpMeEllipse::initTracking(const vpImage &I, std::vector *opt_ips, bool trackCircle, bool trackArc) +#endif +{ +#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) + if (!opt_ips.has_value()) +#else + if (opt_ips == nullptr) +#endif + { + initTracking(I, trackCircle, trackArc); + return; + } + + if (opt_ips->size() != 0) { + initTracking(I, *opt_ips, trackCircle, trackArc); + return; + } + + unsigned int n = 5; // by default, 5 points for an ellipse + const unsigned int nForCircle = 3; + m_trackCircle = trackCircle; + if (trackCircle) { + n = nForCircle; + } + opt_ips->resize(n); + m_trackArc = trackArc; + + vpDisplay::flush(I); + + if (m_trackCircle) { + if (m_trackArc) { + std::cout << "First and third points specify the extremities of the arc of circle (clockwise)" << std::endl; + } + for (unsigned int k = 0; k < n; ++k) { + std::cout << "Click point " << (k + 1) << "/" << n << " on the circle " << std::endl; + vpDisplay::getClick(I, (*opt_ips)[k], true); + const unsigned int crossSize = 10; + vpDisplay::displayCross(I, (*opt_ips)[k], crossSize, vpColor::red); + vpDisplay::flush(I); + std::cout << (*opt_ips)[k] << std::endl; + } + } + else { + if (m_trackArc) { + std::cout << "First and fifth points specify the extremities of the arc of ellipse (clockwise)" << std::endl; + } + for (unsigned int k = 0; k < n; ++k) { + std::cout << "Click point " << (k + 1) << "/" << n << " on the ellipse " << std::endl; + vpDisplay::getClick(I, (*opt_ips)[k], true); + const unsigned int crossSize = 10; + vpDisplay::displayCross(I, (*opt_ips)[k], crossSize, vpColor::red); + vpDisplay::flush(I); + std::cout << (*opt_ips)[k] << std::endl; + } + } + initTracking(I, *opt_ips, trackCircle, trackArc); +} + void vpMeEllipse::initTracking(const vpImage &I, const std::vector &iP, bool trackCircle, bool trackArc) {