diff --git a/ChangeLog.txt b/ChangeLog.txt index 758f9b1f53..05179dc2b8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -90,6 +90,7 @@ ViSP 3.x.x (Version in development) . [#1485] Build issue around nlohmann_json usage with VTK 9.2.0 or more recent version used as an embedded 3rdparty by PCL . [#1494] Memory management issue in vpArray2D::resize() + . [#1495] vpMeLine is unable to seek extremities ---------------------------------------------- ViSP 3.6.0 (released September 22, 2023) - Contributors: diff --git a/example/tracking/trackMeCircle.cpp b/example/tracking/trackMeCircle.cpp index 3beca9c4f2..8050802c87 100644 --- a/example/tracking/trackMeCircle.cpp +++ b/example/tracking/trackMeCircle.cpp @@ -56,13 +56,12 @@ #include #include +#include #include #include #include #include #include - -#include #include #include diff --git a/example/tracking/trackMeEllipse.cpp b/example/tracking/trackMeEllipse.cpp index 36f25fded1..14c2f752b0 100644 --- a/example/tracking/trackMeEllipse.cpp +++ b/example/tracking/trackMeEllipse.cpp @@ -1,7 +1,6 @@ -/**************************************************************************** - * +/* * ViSP, open source Visual Servoing Platform software. - * Copyright (C) 2005 - 2023 by Inria. All rights reserved. + * Copyright (C) 2005 - 2024 by Inria. All rights reserved. * * This software is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,8 +29,7 @@ * * Description: * Tracking of an ellipse. - * -*****************************************************************************/ + */ /*! \file trackMeEllipse.cpp @@ -316,8 +314,8 @@ int main(int argc, const char **argv) // it size is not defined yet, it will be defined when the image is // read on the disk vpImage I; - vpDisplay *display = nullptr; + vpVideoReader g; try { // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH @@ -336,8 +334,9 @@ int main(int argc, const char **argv) } // Get the option values - if (!opt_ipath.empty()) + if (!opt_ipath.empty()) { ipath = opt_ipath; + } // Compare ipath and env_ipath. If they differ, we take into account // the input path coming from the command line option @@ -374,7 +373,6 @@ int main(int argc, const char **argv) thickness += 1; } - vpVideoReader g; if (opt_ppath.empty()) { // Set the path location of the image sequence #if VISP_HAVE_DATASET_VERSION >= 0x030600 @@ -398,7 +396,7 @@ int main(int argc, const char **argv) g.open(I); if (opt_display) { - // We open a window using either X11, GTK or GDI. + // We open a window using either X11, GTK, GDI or OpenCV #if defined(VISP_HAVE_X11) display = new vpDisplayX; #elif defined(VISP_HAVE_GTK) diff --git a/example/tracking/trackMeLine.cpp b/example/tracking/trackMeLine.cpp index 5bc03dda0d..8fb9be47c2 100644 --- a/example/tracking/trackMeLine.cpp +++ b/example/tracking/trackMeLine.cpp @@ -1,7 +1,6 @@ -/**************************************************************************** - * +/* * ViSP, open source Visual Servoing Platform software. - * Copyright (C) 2005 - 2023 by Inria. All rights reserved. + * Copyright (C) 2005 - 2024 by Inria. All rights reserved. * * This software is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,8 +29,7 @@ * * Description: * Tracking of a line. - * -*****************************************************************************/ + */ /*! \file trackMeLine.cpp @@ -59,20 +57,18 @@ #include #include #include +#include #include #include #include #include #include - +#include +#include #include - #include #include -#include -#include - // List of allowed command line options #define GETOPTARGS "cdf:hi:l:p:s:" @@ -222,25 +218,23 @@ bool getOptions(int argc, const char **argv, std::string &ipath, std::string &pp int main(int argc, const char **argv) { #if defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV) - try { - std::string env_ipath; - std::string opt_ipath; - std::string ipath; - std::string opt_ppath; - std::string dirname; - std::string filename; - unsigned int opt_first = 1; - unsigned int opt_last = 30; - unsigned int opt_step = 1; - bool opt_click_allowed = true; - bool opt_display = true; - -#if VISP_HAVE_DATASET_VERSION >= 0x030600 - std::string ext("png"); -#else - std::string ext("pgm"); -#endif + std::string env_ipath; + std::string opt_ipath; + std::string ipath; + std::string opt_ppath; + std::string videoname; + unsigned int opt_first = 1; + unsigned int opt_last = 30; + unsigned int opt_step = 1; + bool opt_click_allowed = true; + bool opt_display = true; + unsigned int thickness = 1; + + vpImage I; + vpDisplay *display = nullptr; + vpVideoReader g; + try { // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH // environment variable value env_ipath = vpIoTools::getViSPImagesDataPath(); @@ -256,8 +250,9 @@ int main(int argc, const char **argv) } // Get the option values - if (!opt_ipath.empty()) + if (!opt_ipath.empty()) { ipath = opt_ipath; + } // Compare ipath and env_ipath. If they differ, we take into account // the input path coming from the command line option @@ -284,76 +279,42 @@ int main(int argc, const char **argv) return EXIT_FAILURE; } - // Declare an image, this is a gray level image (unsigned char) - // it size is not defined yet, it will be defined when the image will - // read on the disk - vpImage I; - - unsigned iter = opt_first; - std::ostringstream s; - char cfilename[FILENAME_MAX]; - + vpVideoReader g; if (opt_ppath.empty()) { - - // Warning : - // The image sequence is not provided with the ViSP package - // therefore the program will return an error : - // !! couldn't read file visp-images/mire-2/image.0001.png - // - // ViSP dataset is available on the visp www site - // https://visp.inria.fr/download/. - - // Set the path location of the image sequence - dirname = vpIoTools::createFilePath(ipath, "line"); - - // Build the name of the image file - s.setf(std::ios::right, std::ios::adjustfield); - s << "image." << std::setw(4) << std::setfill('0') << iter << "." << ext; - filename = vpIoTools::createFilePath(dirname, s.str()); + // Set the path location of the image sequence +#if VISP_HAVE_DATASET_VERSION >= 0x030600 + videoname = vpIoTools::createFilePath(ipath, "line/image.%04d.png"); +#else + videoname = vpIoTools::createFilePath(ipath, "line/image.%04d.pgm"); +#endif + g.setFileName(videoname); } else { - snprintf(cfilename, FILENAME_MAX, opt_ppath.c_str(), iter); - filename = cfilename; + g.setFileName(opt_ppath); } - // Read the image named "filename", and put the bitmap into the image structure I. - // I is initialized to the correct size - // - // vpImageIo::read() may throw various exception if, for example, - // the file does not exist, or if the memory cannot be allocated - try { - vpCTRACE << "Load: " << filename << std::endl; - - vpImageIo::read(I, filename); + if (opt_first > 0) { + g.setFirstFrameIndex(opt_first); } - catch (...) { - // If an exception is thrown by vpImageIo::read() it will result in the end of the program. - std::cerr << std::endl << "ERROR:" << std::endl; - std::cerr << " Cannot read " << filename << std::endl; - if (opt_ppath.empty()) { - std::cerr << " Check your -i " << ipath << " option " << std::endl - << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl; - } - else { - std::cerr << " Check your -p " << opt_ppath << " option " << std::endl; - } - return EXIT_FAILURE; + if (opt_last > 0) { + g.setLastFrameIndex(opt_last); } + g.setFrameStep(opt_step); + g.open(I); - // We open a window using either X11, GTK or GDI. + if (opt_display) { + // We open a window using either X11, GTK, GDI or OpenCV #if defined(VISP_HAVE_X11) - vpDisplayX display; + display = new vpDisplayX; #elif defined(VISP_HAVE_GTK) - vpDisplayGTK display; + display = new vpDisplayGTK; #elif defined(VISP_HAVE_GDI) - vpDisplayGDI display; + display = new vpDisplayGDI; #elif defined(HAVE_OPENCV_HIGHGUI) - vpDisplayOpenCV display; + display = new vpDisplayOpenCV; #endif - - if (opt_display) { // Display size is automatically defined by the image (I) size - display.init(I, 100, 100, "Display..."); + display->init(I, 10, 10, "Current image"); // Display the image // The image class has a member that specify a pointer toward // the display that has been initialized in the display declaration @@ -363,7 +324,7 @@ int main(int argc, const char **argv) vpDisplay::flush(I); } - vpMeLine L1; + vpMeLine me_line; vpMe me; me.setRange(15); @@ -371,24 +332,38 @@ int main(int argc, const char **argv) me.setLikelihoodThresholdType(vpMe::NORMALIZED_THRESHOLD); me.setThreshold(20); - L1.setMe(&me); - L1.setDisplay(vpMeSite::RANGE_RESULT); + me_line.setMe(&me); + me_line.setDisplay(vpMeSite::RANGE_RESULT); + + std::cout << "Video settings" << std::endl; + std::cout << " Name : " << g.getFrameName() << std::endl; + std::cout << " First image: " << g.getFirstFrameIndex() << std::endl; + std::cout << " Last image : " << g.getLastFrameIndex() << std::endl; + std::cout << " Step : " << g.getFrameStep() << std::endl; + std::cout << " Image size : " << I.getWidth() << " x " << I.getHeight() << std::endl; + + std::cout << "Moving-edges settings" << std::endl; + std::cout << " Sample step : " << me_line.getMe()->getSampleStep() << std::endl; + std::cout << " Range : " << me_line.getMe()->getRange() << std::endl; + std::cout << " Threshold type: " << (me_line.getMe()->getLikelihoodThresholdType() == vpMe::NORMALIZED_THRESHOLD ? "normalized" : "old threshold (to be avoided)") << std::endl; + std::cout << " Threshold : " << me_line.getMe()->getThreshold() << std::endl; if (opt_display && opt_click_allowed) - L1.initTracking(I); + me_line.initTracking(I); else { vpImagePoint ip1, ip2; ip1.set_i(96); ip1.set_j(191); ip2.set_i(122); ip2.set_j(211); - L1.initTracking(I, ip1, ip2); + me_line.initTracking(I, ip1, ip2); } - if (opt_display) - L1.display(I, vpColor::green); + if (opt_display) { + me_line.display(I, vpColor::green); + } - L1.track(I); + me_line.track(I); if (opt_display && opt_click_allowed) { std::cout << "A click to continue..." << std::endl; vpDisplay::getClick(I); @@ -398,42 +373,41 @@ int main(int argc, const char **argv) vpFeatureLine l; vpCameraParameters cam; - vpImage Ic; - while (iter < opt_last) { - std::cout << "----------------------------------------------------------" << std::endl; - // set the new image name - s.str(""); - s << "image." << std::setw(4) << std::setfill('0') << iter << "." << ext; - filename = vpIoTools::createFilePath(dirname, s.str()); - // read the image - vpImageIo::read(I, filename); + + bool quit = false; + while (!g.end() && !quit) { + g.acquire(I); + std::cout << "Process image " << g.getFrameIndex() << std::endl; if (opt_display) { // Display the image vpDisplay::display(I); + if (opt_click_allowed) { + vpDisplay::displayText(I, 40, 10, "Click to exit...", vpColor::red); + } } - std::cout << "Tracking on image: " << filename << std::endl; - L1.track(I); + me_line.track(I); - vpTRACE("L1 : %f %f", L1.getRho(), vpMath::deg(L1.getTheta())); - vpFeatureBuilder::create(l, cam, L1); - vpTRACE("L1 : %f %f", l.getRho(), vpMath::deg(l.getTheta())); + vpTRACE("me_line : %f %f", me_line.getRho(), vpMath::deg(me_line.getTheta())); + vpFeatureBuilder::create(l, cam, me_line); + vpTRACE("me_line : %f %f", l.getRho(), vpMath::deg(l.getTheta())); if (opt_display) { - L1.display(I, vpColor::green); + me_line.display(I, vpColor::green, thickness); vpDisplay::flush(I); - if (opt_click_allowed) { - std::cout << "A click to continue..." << std::endl; - vpDisplay::getClick(I); + } + if (opt_display && opt_click_allowed) { + if (vpDisplay::getClick(I, false)) { + quit = true; } } - - iter += opt_step; } - if (opt_display && opt_click_allowed) { - std::cout << "A click to exit..." << std::endl; + if (opt_display && opt_click_allowed && !quit) { vpDisplay::getClick(I); } + if (display) { + delete display; + } return EXIT_SUCCESS; } catch (const vpException &e) { diff --git a/modules/tracker/mbt/src/edge/vpMbtMeLine.cpp b/modules/tracker/mbt/src/edge/vpMbtMeLine.cpp index a433359e48..bf99e47adf 100644 --- a/modules/tracker/mbt/src/edge/vpMbtMeLine.cpp +++ b/modules/tracker/mbt/src/edge/vpMbtMeLine.cpp @@ -171,29 +171,30 @@ void vpMbtMeLine::sample(const vpImage &I, bool doNoTrack) vpImagePoint iP; iP.set_i(is); iP.set_j(js); - unsigned int is_uint = static_cast(is); - unsigned int js_uint = static_cast(js); // If point is in the image, add to the sample list - if ((!outOfImage(iP, (int)(m_me->getRange() + m_me->getMaskSize() + 1), nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint) - && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { - vpMeSite pix; - pix.init(iP.get_i(), iP.get_j(), m_delta, 0, m_sign); - pix.setDisplay(m_selectDisplay); - pix.setState(vpMeSite::NO_SUPPRESSION); - const double marginRatio = m_me->getThresholdMarginRatio(); - double convolution = pix.convolution(I, m_me); - double contrastThreshold = fabs(convolution) * marginRatio; - pix.setContrastThreshold(contrastThreshold, *m_me); - - if (!doNoTrack) { - pix.track(I, m_me, false); - } + if (!outOfImage(iP, (int)(m_me->getRange() + m_me->getMaskSize() + 1), nbrows, nbcols)) { + unsigned int is_uint = static_cast(is); + unsigned int js_uint = static_cast(js); + if (inRoiMask(m_mask, is_uint, js_uint) && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { + vpMeSite pix; + pix.init(iP.get_i(), iP.get_j(), m_delta, 0, m_sign); + pix.setDisplay(m_selectDisplay); + pix.setState(vpMeSite::NO_SUPPRESSION); + const double marginRatio = m_me->getThresholdMarginRatio(); + double convolution = pix.convolution(I, m_me); + double contrastThreshold = fabs(convolution) * marginRatio; + pix.setContrastThreshold(contrastThreshold, *m_me); + + if (!doNoTrack) { + pix.track(I, m_me, false); + } - if (vpDEBUG_ENABLE(3)) { - vpDisplay::displayCross(I, iP, 2, vpColor::blue); - } + if (vpDEBUG_ENABLE(3)) { + vpDisplay::displayCross(I, iP, 2, vpColor::blue); + } - m_meList.push_back(pix); + m_meList.push_back(pix); + } } is += stepi; js += stepj; diff --git a/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp b/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp index fffd6e8f13..dc143cadcb 100644 --- a/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp +++ b/modules/tracker/me/src/moving-edges/vpMeEllipse.cpp @@ -311,25 +311,26 @@ void vpMeEllipse::sample(const vpImage &I, bool doNotTrack) computePointOnEllipse(ang, iP); // If point is in the image, add to the sample list // Check done in (i,j) frame) - unsigned int is_uint = static_cast(iP.get_i()); - unsigned int js_uint = static_cast(iP.get_j()); - if ((!outOfImage(iP, 0, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint) - && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { - const unsigned int crossSize = 5; - vpDisplay::displayCross(I, iP, crossSize, vpColor::red); - - double theta = computeTheta(iP); - vpMeSite pix; - // (i,j) frame used for vpMeSite - pix.init(iP.get_i(), iP.get_j(), theta); - pix.setDisplay(m_selectDisplay); - pix.setState(vpMeSite::NO_SUPPRESSION); - const double marginRatio = m_me->getThresholdMarginRatio(); - double convolution = pix.convolution(I, m_me); - double contrastThreshold = fabs(convolution) * marginRatio; - pix.setContrastThreshold(contrastThreshold, *m_me); - m_meList.push_back(pix); - m_angleList.push_back(ang); + if (!outOfImage(iP, 0, nbrows, nbcols)) { + unsigned int is_uint = static_cast(iP.get_i()); + unsigned int js_uint = static_cast(iP.get_j()); + if (inRoiMask(m_mask, is_uint, js_uint) && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { + const unsigned int crossSize = 5; + vpDisplay::displayCross(I, iP, crossSize, vpColor::red); + + double theta = computeTheta(iP); + vpMeSite pix; + // (i,j) frame used for vpMeSite + pix.init(iP.get_i(), iP.get_j(), theta); + pix.setDisplay(m_selectDisplay); + pix.setState(vpMeSite::NO_SUPPRESSION); + const double marginRatio = m_me->getThresholdMarginRatio(); + double convolution = pix.convolution(I, m_me); + double contrastThreshold = fabs(convolution) * marginRatio; + pix.setContrastThreshold(contrastThreshold, *m_me); + m_meList.push_back(pix); + m_angleList.push_back(ang); + } } ang += incr; } @@ -375,9 +376,63 @@ unsigned int vpMeEllipse::plugHoles(const vpImage &I) while (ang < (nextang - incr)) { vpImagePoint iP; computePointOnEllipse(ang, iP); + if (!outOfImage(iP, 0, nbrows, nbcols)) { + unsigned int is_uint = static_cast(iP.get_i()); + unsigned int js_uint = static_cast(iP.get_j()); + if (inRoiMask(m_mask, is_uint, js_uint)) { + double theta = computeTheta(iP); + vpMeSite pix; + pix.init(iP.get_i(), iP.get_j(), theta); + pix.setDisplay(m_selectDisplay); + pix.setState(vpMeSite::NO_SUPPRESSION); + double convolution = pix.convolution(I, m_me); + double contrastThreshold = fabs(convolution) * marginRatio; + pix.setContrastThreshold(contrastThreshold, *m_me); + pix.track(I, m_me, false); + if (pix.getState() == vpMeSite::NO_SUPPRESSION) { // good point + ++nb_pts_added; + iP.set_ij(pix.get_ifloat(), pix.get_jfloat()); + double new_ang = computeAngleOnEllipse(iP); + if ((new_ang - ang) > M_PI) { + new_ang -= 2.0 * M_PI; + } + else if ((ang - new_ang) > M_PI) { + new_ang += 2.0 * M_PI; + } + m_meList.insert(meList, pix); + m_angleList.insert(angleList, new_ang); + } + } + } + ang += incr; + } + } + ang = nextang; + ++angleList; + ++meList; + } + + // Add points in case two neighboring points are too far away + angleList = m_angleList.begin(); + ang = *angleList; + meList = m_meList.begin(); + vpMeSite pix1 = *meList; + ++angleList; + ++meList; + while (meList != m_meList.end()) { + double nextang = *angleList; + vpMeSite pix2 = *meList; + double dist = sqrt(((pix1.get_ifloat() - pix2.get_ifloat()) * (pix1.get_ifloat() - pix2.get_ifloat())) + + ((pix1.get_jfloat() - pix2.get_jfloat()) * (pix1.get_jfloat() - pix2.get_jfloat()))); + // Only one point is added if two neighboring points are too far away + if (dist > (2.0 * m_me->getSampleStep())) { + ang = (nextang + ang) / 2.0; // point added at mid angle + vpImagePoint iP; + computePointOnEllipse(ang, iP); + if (!outOfImage(iP, 0, nbrows, nbcols)) { unsigned int is_uint = static_cast(iP.get_i()); unsigned int js_uint = static_cast(iP.get_j()); - if ((!outOfImage(iP, 0, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint)) { + if (inRoiMask(m_mask, is_uint, js_uint)) { double theta = computeTheta(iP); vpMeSite pix; pix.init(iP.get_i(), iP.get_j(), theta); @@ -401,44 +456,41 @@ unsigned int vpMeEllipse::plugHoles(const vpImage &I) m_angleList.insert(angleList, new_ang); } } - ang += incr; } } ang = nextang; + pix1 = pix2; ++angleList; ++meList; } - // Add points in case two neighboring points are too far away - angleList = m_angleList.begin(); - ang = *angleList; + // Try to fill the first extremity: from alpha_min - incr to alpha1 + incr/2 meList = m_meList.begin(); - vpMeSite pix1 = *meList; - ++angleList; - ++meList; - while (meList != m_meList.end()) { - double nextang = *angleList; - vpMeSite pix2 = *meList; - double dist = sqrt(((pix1.get_ifloat() - pix2.get_ifloat()) * (pix1.get_ifloat() - pix2.get_ifloat())) - + ((pix1.get_jfloat() - pix2.get_jfloat()) * (pix1.get_jfloat() - pix2.get_jfloat()))); - // Only one point is added if two neighboring points are too far away - if (dist > (2.0 * m_me->getSampleStep())) { - ang = (nextang + ang) / 2.0; // point added at mid angle - vpImagePoint iP; - computePointOnEllipse(ang, iP); + pix1 = *meList; + unsigned int nbpts = 0; + // Add - incr/2.0 to avoid being too close to 0 + if ((m_alphamin - m_alpha1 - (incr / 2.0)) > 0.0) { + nbpts = static_cast(floor((m_alphamin - m_alpha1 - (incr / 2.0)) / incr)); + } + ang = m_alphamin - incr; + for (unsigned int i = 0; i < nbpts; ++i) { + vpImagePoint iP; + computePointOnEllipse(ang, iP); + if (!outOfImage(iP, 0, nbrows, nbcols)) { unsigned int is_uint = static_cast(iP.get_i()); unsigned int js_uint = static_cast(iP.get_j()); - if ((!outOfImage(iP, 0, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint)) { + if (inRoiMask(m_mask, is_uint, js_uint)) { double theta = computeTheta(iP); vpMeSite pix; pix.init(iP.get_i(), iP.get_j(), theta); pix.setDisplay(m_selectDisplay); pix.setState(vpMeSite::NO_SUPPRESSION); + // --comment: pix dot setContrastThreshold of pix1 dot getContrastThreshold() comma *m_me double convolution = pix.convolution(I, m_me); double contrastThreshold = fabs(convolution) * marginRatio; pix.setContrastThreshold(contrastThreshold, *m_me); pix.track(I, m_me, false); - if (pix.getState() == vpMeSite::NO_SUPPRESSION) { // good point + if (pix.getState() == vpMeSite::NO_SUPPRESSION) { ++nb_pts_added; iP.set_ij(pix.get_ifloat(), pix.get_jfloat()); double new_ang = computeAngleOnEllipse(iP); @@ -448,56 +500,11 @@ unsigned int vpMeEllipse::plugHoles(const vpImage &I) else if ((ang - new_ang) > M_PI) { new_ang += 2.0 * M_PI; } - m_meList.insert(meList, pix); - m_angleList.insert(angleList, new_ang); + m_meList.push_front(pix); + m_angleList.push_front(new_ang); } } } - ang = nextang; - pix1 = pix2; - ++angleList; - ++meList; - } - - // Try to fill the first extremity: from alpha_min - incr to alpha1 + incr/2 - meList = m_meList.begin(); - pix1 = *meList; - unsigned int nbpts = 0; - // Add - incr/2.0 to avoid being too close to 0 - if ((m_alphamin - m_alpha1 - (incr / 2.0)) > 0.0) { - nbpts = static_cast(floor((m_alphamin - m_alpha1 - (incr / 2.0)) / incr)); - } - ang = m_alphamin - incr; - for (unsigned int i = 0; i < nbpts; ++i) { - vpImagePoint iP; - computePointOnEllipse(ang, iP); - unsigned int is_uint = static_cast(iP.get_i()); - unsigned int js_uint = static_cast(iP.get_j()); - if ((!outOfImage(iP, 0, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint)) { - double theta = computeTheta(iP); - vpMeSite pix; - pix.init(iP.get_i(), iP.get_j(), theta); - pix.setDisplay(m_selectDisplay); - pix.setState(vpMeSite::NO_SUPPRESSION); - // --comment: pix dot setContrastThreshold of pix1 dot getContrastThreshold() comma *m_me - double convolution = pix.convolution(I, m_me); - double contrastThreshold = fabs(convolution) * marginRatio; - pix.setContrastThreshold(contrastThreshold, *m_me); - pix.track(I, m_me, false); - if (pix.getState() == vpMeSite::NO_SUPPRESSION) { - ++nb_pts_added; - iP.set_ij(pix.get_ifloat(), pix.get_jfloat()); - double new_ang = computeAngleOnEllipse(iP); - if ((new_ang - ang) > M_PI) { - new_ang -= 2.0 * M_PI; - } - else if ((ang - new_ang) > M_PI) { - new_ang += 2.0 * M_PI; - } - m_meList.push_front(pix); - m_angleList.push_front(new_ang); - } - } ang -= incr; } @@ -512,30 +519,32 @@ unsigned int vpMeEllipse::plugHoles(const vpImage &I) for (unsigned int i = 0; i < nbpts; ++i) { vpImagePoint iP; computePointOnEllipse(ang, iP); - unsigned int is_uint = static_cast(iP.get_i()); - unsigned int js_uint = static_cast(iP.get_j()); - if ((!outOfImage(iP, 0, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint)) { - double theta = computeTheta(iP); - vpMeSite pix; - pix.init(iP.get_i(), iP.get_j(), theta); - pix.setDisplay(m_selectDisplay); - pix.setState(vpMeSite::NO_SUPPRESSION); - double convolution = pix.convolution(I, m_me); - double contrastThreshold = fabs(convolution) * marginRatio; - pix.setContrastThreshold(contrastThreshold, *m_me); - pix.track(I, m_me, false); - if (pix.getState() == vpMeSite::NO_SUPPRESSION) { - ++nb_pts_added; - iP.set_ij(pix.get_ifloat(), pix.get_jfloat()); - double new_ang = computeAngleOnEllipse(iP); - if ((new_ang - ang) > M_PI) { - new_ang -= 2.0 * M_PI; - } - else if ((ang - new_ang) > M_PI) { - new_ang += 2.0 * M_PI; + if (!outOfImage(iP, 0, nbrows, nbcols)) { + unsigned int is_uint = static_cast(iP.get_i()); + unsigned int js_uint = static_cast(iP.get_j()); + if (inRoiMask(m_mask, is_uint, js_uint)) { + double theta = computeTheta(iP); + vpMeSite pix; + pix.init(iP.get_i(), iP.get_j(), theta); + pix.setDisplay(m_selectDisplay); + pix.setState(vpMeSite::NO_SUPPRESSION); + double convolution = pix.convolution(I, m_me); + double contrastThreshold = fabs(convolution) * marginRatio; + pix.setContrastThreshold(contrastThreshold, *m_me); + pix.track(I, m_me, false); + if (pix.getState() == vpMeSite::NO_SUPPRESSION) { + ++nb_pts_added; + iP.set_ij(pix.get_ifloat(), pix.get_jfloat()); + double new_ang = computeAngleOnEllipse(iP); + if ((new_ang - ang) > M_PI) { + new_ang -= 2.0 * M_PI; + } + else if ((ang - new_ang) > M_PI) { + new_ang += 2.0 * M_PI; + } + m_meList.push_back(pix); + m_angleList.push_back(new_ang); } - m_meList.push_back(pix); - m_angleList.push_back(new_ang); } } ang += incr; diff --git a/modules/tracker/me/src/moving-edges/vpMeLine.cpp b/modules/tracker/me/src/moving-edges/vpMeLine.cpp index 43aafd0b3d..b585f37bae 100644 --- a/modules/tracker/me/src/moving-edges/vpMeLine.cpp +++ b/modules/tracker/me/src/moving-edges/vpMeLine.cpp @@ -518,13 +518,17 @@ void vpMeLine::seekExtremities(const vpImage &I) double sample_step = (double)m_me->getSampleStep(); vpMeSite P; + P.init((int)m_PExt[0].m_ifloat, (int)m_PExt[0].m_jfloat, m_delta_1, 0, m_sign); P.setDisplay(m_selectDisplay); + const double marginRatio = m_me->getThresholdMarginRatio(); + double convolution = P.convolution(I, m_me); + double contrastThreshold = fabs(convolution) * marginRatio; + P.setContrastThreshold(contrastThreshold, *m_me); unsigned int memory_range = m_me->getRange(); m_me->setRange(1); - for (int i = 0; i < 3; i++) { P.m_ifloat = P.m_ifloat + di * sample_step; P.m_i = static_cast(P.m_ifloat); @@ -535,28 +539,32 @@ void vpMeLine::seekExtremities(const vpImage &I) iP.set_i(P.m_ifloat); iP.set_j(P.m_jfloat); - unsigned int is_uint = static_cast(P.m_ifloat); - unsigned int js_uint = static_cast(P.m_jfloat); - if ((!outOfImage(iP, 5, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint) - && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { - P.track(I, m_me, false); - - if (P.getState() == vpMeSite::NO_SUPPRESSION) { - m_meList.push_back(P); - if (vpDEBUG_ENABLE(3)) { - vpDisplay::displayCross(I, iP, 5, vpColor::green); + // First test to ensure that iP coordinates are > 0 before casting to unsigned int + if (!outOfImage(iP, 5, nbrows, nbcols)) { + unsigned int is_uint = static_cast(P.m_ifloat); + unsigned int js_uint = static_cast(P.m_jfloat); + if (inRoiMask(m_mask, is_uint, js_uint) && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { + P.track(I, m_me, false); + if (P.getState() == vpMeSite::NO_SUPPRESSION) { + m_meList.push_back(P); + if (vpDEBUG_ENABLE(3)) { + vpDisplay::displayCross(I, iP, 5, vpColor::green); + } } - } - else { - if (vpDEBUG_ENABLE(3)) { - vpDisplay::displayCross(I, iP, 10, vpColor::blue); + else { + if (vpDEBUG_ENABLE(3)) { + vpDisplay::displayCross(I, iP, 10, vpColor::blue); + } } } } } - P.init((int)m_PExt[1].m_ifloat, (int)m_PExt[1].m_jfloat, m_delta_1, 0, m_sign); P.setDisplay(m_selectDisplay); + convolution = P.convolution(I, m_me); + contrastThreshold = fabs(convolution) * marginRatio; + P.setContrastThreshold(contrastThreshold, *m_me); + for (int i = 0; i < 3; i++) { P.m_ifloat = P.m_ifloat - di * sample_step; P.m_i = static_cast(P.m_ifloat); @@ -567,21 +575,22 @@ void vpMeLine::seekExtremities(const vpImage &I) iP.set_i(P.m_ifloat); iP.set_j(P.m_jfloat); - unsigned int is_uint = static_cast(P.m_ifloat); - unsigned int js_uint = static_cast(P.m_jfloat); - if ((!outOfImage(iP, 5, nbrows, nbcols)) && inRoiMask(m_mask, is_uint, js_uint) - && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { - P.track(I, m_me, false); - - if (P.getState() == vpMeSite::NO_SUPPRESSION) { - m_meList.push_back(P); - if (vpDEBUG_ENABLE(3)) { - vpDisplay::displayCross(I, iP, 5, vpColor::green); + // First test to ensure that iP coordinates are > 0 before casting to unsigned int + if (!outOfImage(iP, 5, nbrows, nbcols)) { + unsigned int is_uint = static_cast(P.m_ifloat); + unsigned int js_uint = static_cast(P.m_jfloat); + if (inRoiMask(m_mask, is_uint, js_uint) && inMeMaskCandidates(m_maskCandidates, is_uint, js_uint)) { + P.track(I, m_me, false); + if (P.getState() == vpMeSite::NO_SUPPRESSION) { + m_meList.push_back(P); + if (vpDEBUG_ENABLE(3)) { + vpDisplay::displayCross(I, iP, 5, vpColor::green); + } } - } - else { - if (vpDEBUG_ENABLE(3)) { - vpDisplay::displayCross(I, iP, 10, vpColor::blue); + else { + if (vpDEBUG_ENABLE(3)) { + vpDisplay::displayCross(I, iP, 10, vpColor::blue); + } } } }