Skip to content

Commit

Permalink
[CORPS] Added a vpImageFilter::canny that takes both the lower and up…
Browse files Browse the repository at this point in the history
…per Canny thresholds as parameters + apply Gaussian blur and Sobel filters before calling cv::Canny
  • Loading branch information
rlagneau committed Sep 12, 2023
1 parent a32e92d commit dde4641
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 6 deletions.
3 changes: 3 additions & 0 deletions modules/core/include/visp3/core/vpImageFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class VISP_EXPORT vpImageFilter
static void canny(const vpImage<unsigned char> &I, vpImage<unsigned char> &Ic, unsigned int gaussianFilterSize,
float thresholdCanny, unsigned int apertureSobel);

static void canny(const vpImage<unsigned char> &I, vpImage<unsigned char> &Ic, unsigned int gaussianFilterSize,
float lowerThresholdCanny, float higherThresholdCanny, unsigned int apertureSobel);

/*!
Apply a 1x3 derivative filter to an image pixel.
Expand Down
71 changes: 65 additions & 6 deletions modules/core/src/image/vpImageFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,24 +297,83 @@ int main()
*/
void vpImageFilter::canny(const vpImage<unsigned char> &Isrc, vpImage<unsigned char> &Ires,
unsigned int gaussianFilterSize, float thresholdCanny, unsigned int apertureSobel)
{
vpImageFilter::canny(Isrc, Ires, gaussianFilterSize, thresholdCanny / 3.f, thresholdCanny, apertureSobel);
}

/*!
Apply the Canny edge operator on the image \e Isrc and return the resulting
image \e Ires.
The following example shows how to use the method:
\code
#include <visp3/core/vpImage.h>
#include <visp3/core/vpImageFilter.h>
int main()
{
// Constants for the Canny operator.
const unsigned int gaussianFilterSize = 5;
const float upperThresholdCanny = 15;
const float lowerThresholdCanny = 5;
const unsigned int apertureSobel = 3;
// Image for the Canny edge operator
vpImage<unsigned char> Isrc;
vpImage<unsigned char> Icanny;
// First grab the source image Isrc.
// Apply the Canny edge operator and set the Icanny image.
vpImageFilter::canny(Isrc, Icanny, gaussianFilterSize, lowerThresholdCanny, upperThresholdCanny, apertureSobel);
return (0);
}
\endcode
\param Isrc : Image to apply the Canny edge detector to.
\param Ires : Filtered image (255 means an edge, 0 otherwise).
\param gaussianFilterSize : The size of the mask of the Gaussian filter to
apply (an odd number).
\param lowerThreshold : The lower threshold for the Canny operator. Values lower
than this value are rejected. If negative, it will be set to one third
of the thresholdCanny .
\param upperThreshold : The upper threshold for the Canny operator. Only value
greater than this value are marked as an edge. If negative, it will be automatically
computed, along with the lower threshold. Otherwise, the lower threshold will be set to one third
of the thresholdCanny .
\param apertureSobel : Size of the mask for the Sobel operator (odd number).
*/
void vpImageFilter::canny(const vpImage<unsigned char> &Isrc, vpImage<unsigned char> &Ires,
unsigned int gaussianFilterSize, float lowerThreshold, float upperThreshold, unsigned int apertureSobel)
{
#if defined(HAVE_OPENCV_IMGPROC)
cv::Mat img_cvmat, cv_I_blur, edges_cvmat;
cv::Mat img_cvmat, cv_I_blur, cv_dx, cv_dy, edges_cvmat;
vpImageConvert::convert(Isrc, img_cvmat);
cv::GaussianBlur(img_cvmat, cv_I_blur, cv::Size((int)gaussianFilterSize, (int)gaussianFilterSize), 0, 0);
float upperCannyThresh = thresholdCanny;
float lowerCannyThresh = thresholdCanny / 3.f;
cv::Sobel(cv_I_blur, cv_dx, CV_16S, 1, 0, apertureSobel);
cv::Sobel(cv_I_blur, cv_dy, CV_16S, 0, 1, apertureSobel);
float upperCannyThresh = upperThreshold;
float lowerCannyThresh = lowerThreshold;
if (upperCannyThresh < 0) {
upperCannyThresh = computeCannyThreshold(img_cvmat, &cv_I_blur, lowerCannyThresh);
}
cv::Canny(cv_I_blur, edges_cvmat, lowerCannyThresh, upperCannyThresh, (int)apertureSobel);
else if (lowerCannyThresh < 0) {
lowerCannyThresh = upperCannyThresh / 3.f;
}
cv::Canny(cv_dx, cv_dy, edges_cvmat, lowerCannyThresh, upperCannyThresh, false);
vpImageConvert::convert(edges_cvmat, Ires);
#else
(void)apertureSobel;
if (thresholdCanny < 0) {
float upperCannyThresh = upperThreshold;
float lowerCannyThresh = lowerThreshold;
if (upperCannyThresh < 0) {
throw(vpException(vpException::badValue, "OpenCV imgproc module missing to be able to compute automatically the Canny thresholds"));
}
vpCannyEdgeDetection edgeDetector(gaussianFilterSize, 0.1, thresholdCanny * 0.5, thresholdCanny);
else if (lowerCannyThresh < 0) {
lowerCannyThresh = upperCannyThresh / 3.;
}
vpCannyEdgeDetection edgeDetector(gaussianFilterSize, 0.1, lowerCannyThresh, upperCannyThresh);
Ires = edgeDetector.detect(Isrc);
#endif
}
Expand Down

0 comments on commit dde4641

Please sign in to comment.