Skip to content

Commit

Permalink
Merge pull request #1224 from rolalaro/vpCircleHoughTransform
Browse files Browse the repository at this point in the history
Small improvements in vpCircleHoughTransform
  • Loading branch information
fspindle authored Sep 2, 2023
2 parents 3f74e10 + 63902af commit 76cc08f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 19 deletions.
2 changes: 1 addition & 1 deletion doc/tutorial/imgproc/tutorial-imgproc-cht.dox
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ You could have also used the following method to get only the `num_best` best
detections:
\code
int num_best; // Set it to the number of circles you want to keep
std::vector<vvpImageCircle> detections = detector.detect(I, num_best);
std::vector<vpImageCircle> detections = detector.detect(I, num_best);
\endcode

Then, you can iterate on the vector of detections using a synthax similar to the following:
Expand Down
4 changes: 4 additions & 0 deletions modules/core/include/visp3/core/vpImageCircle.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
#include <visp3/core/vpImagePoint.h>
#include <visp3/core/vpRect.h>

#if defined(VISP_HAVE_OPENCV)
#include <opencv2/core.hpp>
#endif

/**
* \brief Class that defines a 2D circle in an image.
*/
Expand Down
30 changes: 16 additions & 14 deletions modules/imgproc/include/visp3/imgproc/vpCircleHoughTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

// ViSP includes
#include <visp3/core/vpConfig.h>
#include <visp3/core/vpCannyEdgeDetection.h>
#include <visp3/core/vpImage.h>
#include <visp3/core/vpImageCircle.h>
#include <visp3/core/vpImageDraw.h>
Expand Down Expand Up @@ -69,7 +70,7 @@ class VISP_EXPORT vpCircleHoughTransform
/**
* \brief Class that gather the algorithm parameters.
*/
class CHTransformParameters
class vpCircleHoughTransformParameters
{
private:
// // Gaussian smoothing attributes
Expand Down Expand Up @@ -102,7 +103,7 @@ class VISP_EXPORT vpCircleHoughTransform

friend class vpCircleHoughTransform;
public:
CHTransformParameters()
vpCircleHoughTransformParameters()
: m_gaussianKernelSize(5)
, m_gaussianStdev(1.)
, m_sobelKernelSize(3)
Expand All @@ -123,7 +124,7 @@ class VISP_EXPORT vpCircleHoughTransform
}

/**
* \brief Construct a new CHTransformParameters object.
* \brief Construct a new vpCircleHoughTransformParameters object.
*
* \param[in] gaussianKernelSize Size of the Gaussian filter kernel used to smooth the input image. Must be an odd number.
* \param[in] gaussianStdev Standard deviation of the Gaussian filter.
Expand All @@ -142,7 +143,7 @@ class VISP_EXPORT vpCircleHoughTransform
* \param[in] centerMinDistThresh Two circle candidates whose centers are closer than this threshold are considered for merging.
* \param[in] mergingRadiusDiffThresh Maximum radius difference between two circle candidates to consider merging them.
*/
CHTransformParameters(
vpCircleHoughTransformParameters(
const int &gaussianKernelSize
, const float &gaussianStdev
, const int &sobelKernelSize
Expand Down Expand Up @@ -201,12 +202,12 @@ class VISP_EXPORT vpCircleHoughTransform
// // Configuration from files
#ifdef VISP_HAVE_NLOHMANN_JSON
/**
* \brief Create a new CHTransformParameters from a JSON file.
* \brief Create a new vpCircleHoughTransformParameters from a JSON file.
*
* \param[in] jsonFile The path towards the JSON file.
* \return CHTransformParameters The corresponding CHTransformParameters object.
* \return vpCircleHoughTransformParameters The corresponding vpCircleHoughTransformParameters object.
*/
inline static CHTransformParameters createFromJSON(const std::string &jsonFile)
inline static vpCircleHoughTransformParameters createFromJSON(const std::string &jsonFile)
{
std::ifstream file(jsonFile);
if (!file.good()) {
Expand All @@ -226,7 +227,7 @@ class VISP_EXPORT vpCircleHoughTransform
msg << "Byte position of error: " << e.byte;
throw vpException(vpException::ioError, msg.str());
}
CHTransformParameters params = j; // Call from_json(const json& j, vpDetectorDNN& *this) to read json
vpCircleHoughTransformParameters params = j; // Call from_json(const json& j, vpDetectorDNN& *this) to read json
file.close();
return params;
}
Expand All @@ -253,7 +254,7 @@ class VISP_EXPORT vpCircleHoughTransform
* \param[in] j : The JSON object, resulting from the parsing of a JSON file.
* \param[out] params : The circle Hough transform parameters that will be initialized from the JSON data.
*/
inline friend void from_json(const json &j, CHTransformParameters &params)
inline friend void from_json(const json &j, vpCircleHoughTransformParameters &params)
{
params.m_gaussianKernelSize = j.value("gaussianKernelSize", params.m_gaussianKernelSize);
if ((params.m_gaussianKernelSize % 2) != 1) {
Expand Down Expand Up @@ -311,7 +312,7 @@ class VISP_EXPORT vpCircleHoughTransform
* \param[out] j : A JSON parser object.
* \param[in] params : The circle Hough transform parameters that will be serialized in the json object.
*/
inline friend void to_json(json &j, const CHTransformParameters &params)
inline friend void to_json(json &j, const vpCircleHoughTransformParameters &params)
{
std::pair<unsigned int, unsigned int> radiusLimits = { params.m_minRadius, params.m_maxRadius };

Expand Down Expand Up @@ -341,10 +342,10 @@ class VISP_EXPORT vpCircleHoughTransform

/**
* \brief Construct a new vpCircleHoughTransform object
* from a \b CHTransformParameters object.
* from a \b vpCircleHoughTransformParameters object.
* \param[in] algoParams The parameters of the Circle Hough Transform.
*/
vpCircleHoughTransform(const CHTransformParameters &algoParams);
vpCircleHoughTransform(const vpCircleHoughTransformParameters &algoParams);

/**
* \brief Destroy the vp Circle Hough Transform object
Expand Down Expand Up @@ -452,7 +453,7 @@ class VISP_EXPORT vpCircleHoughTransform
*
* \param[in] algoParams The algorithm parameters.
*/
void init(const CHTransformParameters &algoParams);
void init(const vpCircleHoughTransformParameters &algoParams);

/**
* \brief Set the parameters of the Gaussian filter, that computes the
Expand Down Expand Up @@ -767,7 +768,7 @@ class VISP_EXPORT vpCircleHoughTransform
void mergeCircleCandidates();


CHTransformParameters m_algoParams; /*!< Attributes containing all the algorithm parameters.*/
vpCircleHoughTransformParameters m_algoParams; /*!< Attributes containing all the algorithm parameters.*/
// // Gaussian smoothing attributes
vpArray2D<float> m_fg;
vpArray2D<float> m_fgDg;
Expand All @@ -778,6 +779,7 @@ class VISP_EXPORT vpCircleHoughTransform
vpImage<float> m_dIy; /*!< Gradient along the y-axis of the input image.*/

// // Edge detection attributes
vpCannyEdgeDetection m_cannyVisp; /*!< Edge detector ViSP implementation, used if ViSP has not been compiled with OpenCV imgproc module*/
vpImage<unsigned char> m_edgeMap; /*!< Edge map resulting from the edge detection algorithm.*/

// // Center candidates computation attributes
Expand Down
17 changes: 14 additions & 3 deletions modules/imgproc/src/vpCircleHoughTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ vpCircleHoughTransform::vpCircleHoughTransform()
initGaussianFilters();
}

vpCircleHoughTransform::vpCircleHoughTransform(const CHTransformParameters &algoParams)
vpCircleHoughTransform::vpCircleHoughTransform(const vpCircleHoughTransformParameters &algoParams)
: m_algoParams(algoParams)
{
initGaussianFilters();
}

void
vpCircleHoughTransform::init(const CHTransformParameters &algoParams)
vpCircleHoughTransform::init(const vpCircleHoughTransformParameters &algoParams)
{
m_algoParams = algoParams;
initGaussianFilters();
Expand Down Expand Up @@ -105,6 +105,7 @@ vpCircleHoughTransform::initGaussianFilters()
vpImageFilter::getGaussianKernel(m_fg.data, m_algoParams.m_gaussianKernelSize, m_algoParams.m_gaussianStdev, false);
m_fgDg.resize(1, (m_algoParams.m_gaussianKernelSize + 1)/2);
vpImageFilter::getGaussianDerivativeKernel(m_fgDg.data, m_algoParams.m_gaussianKernelSize, m_algoParams.m_gaussianStdev, false);
m_cannyVisp.setGaussianFilterParameters(m_algoParams.m_gaussianKernelSize, m_algoParams.m_gaussianStdev);
}

std::vector<vpImageCircle>
Expand Down Expand Up @@ -218,10 +219,20 @@ vpCircleHoughTransform::computeGradientsAfterGaussianSmoothing(const vpImage<uns
void
vpCircleHoughTransform::edgeDetection(const vpImage<unsigned char> &I)
{
int cannyThresh = m_algoParams.m_cannyThresh;
#if defined(HAVE_OPENCV_IMGPROC)
float cannyThresh = m_algoParams.m_cannyThresh;
double lowerThresh;
// Apply the Canny edge operator to compute the edge map
// The canny method performs Gaussian blur and gradient computation
if (m_algoParams.m_cannyThresh < 0.) {
cannyThresh = vpImageFilter::computeCannyThreshold(I, lowerThresh);
}
vpImageFilter::canny(I, m_edgeMap, m_algoParams.m_gaussianKernelSize, cannyThresh, m_algoParams.m_sobelKernelSize);
#else
m_cannyVisp.setCannyThresholds(-1, m_algoParams.m_cannyThresh);
m_cannyVisp.setGradients(m_dIx, m_dIy);
m_edgeMap = m_cannyVisp.detect(I);
#endif

for (int i = 0; i < m_algoParams.m_edgeMapFilteringNbIter; i++) {
filterEdgeMap();
Expand Down
22 changes: 21 additions & 1 deletion tutorial/imgproc/hough-transform/tutorial-circle-hough.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ int main(int argc, char **argv)
const int def_gaussianKernelSize = 5;
const double def_gaussianSigma = 1.;
const int def_sobelKernelSize = 3;
#ifdef HAVE_OPENCV_IMGPROC
const double def_cannyThresh = 150.;
#else
const double def_cannyThresh = 25.;
#endif
const int def_nbEdgeFilteringIter = 2;
const std::pair<int, int> def_centerXlimits = std::pair<int, int>(0, 640);
const std::pair<int, int> def_centerYlimits = std::pair<int, int>(0, 480);
Expand Down Expand Up @@ -423,13 +427,25 @@ int main(int argc, char **argv)
TypeInputImage inputType = typeInputImageFromString(opt_input);
switch (inputType) {
case TypeInputImage::FULL_DISKS:
#ifdef HAVE_OPENCV_IMGPROC
opt_centerThresh = 100.;
#else
opt_centerThresh = 75.;
#endif
break;
case TypeInputImage::HALF_DISKS:
#ifdef HAVE_OPENCV_IMGPROC
opt_centerThresh = 50.;
#else
opt_centerThresh = 25.;
#endif
break;
case TypeInputImage::QUARTER_DISKS:
#ifdef HAVE_OPENCV_IMGPROC
opt_centerThresh = 25.;
#else
opt_centerThresh = 15.;
#endif
break;
default:
throw(vpException(vpException::badValue, "Missing center threshold value to use with actual pictures as input. See the help for more information."));
Expand All @@ -441,7 +457,11 @@ int main(int argc, char **argv)
TypeInputImage inputType = typeInputImageFromString(opt_input);
switch (inputType) {
case TypeInputImage::FULL_DISKS:
#ifdef HAVE_OPENCV_IMGPROC
opt_radiusThreshRatio = 5.;
#else
opt_radiusThreshRatio = 1.;
#endif
break;
case TypeInputImage::HALF_DISKS:
opt_radiusThreshRatio = 2.;
Expand All @@ -455,7 +475,7 @@ int main(int argc, char **argv)
}

//! [Algo params]
vpCircleHoughTransform::CHTransformParameters
vpCircleHoughTransform::vpCircleHoughTransformParameters
algoParams(opt_gaussianKernelSize
, opt_gaussianSigma
, opt_sobelKernelSize
Expand Down

0 comments on commit 76cc08f

Please sign in to comment.