34 #include <visp3/core/vpConfig.h>
35 #include <visp3/core/vpImageFilter.h>
36 #include <visp3/core/vpIoTools.h>
37 #include <visp3/core/vpCannyEdgeDetection.h>
50 const std::string &suf)
52 std::string list(pref);
75 name =
"opencv-backend";
78 name =
"visp-backend";
82 return "unknown-backend";
100 while ((i < count) && notFound) {
120 const std::string &suf)
122 std::string list(pref);
145 name =
"gaussianblur+sobel-filtering";
148 name =
"gaussianblur+scharr-filtering";
152 return "unknown-filtering";
168 bool notFound =
true;
170 while ((i < count) && notFound) {
181 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
201 float &lowerThresh,
const unsigned int &gaussianKernelSize,
202 const float &gaussianStdev,
const unsigned int &apertureGradient,
203 const float &lowerThresholdRatio,
const float &upperThresholdRatio,
206 double w = cv_I.cols;
207 double h = cv_I.rows;
209 cv::Mat dI, dIx, dIy, dIx_abs, dIy_abs;
211 if ((p_cv_dIx ==
nullptr) || (p_cv_dIy ==
nullptr)) {
221 cv::convertScaleAbs(dIx, dIx_abs);
222 cv::convertScaleAbs(dIy, dIy_abs);
223 cv::addWeighted(dIx_abs, 1, dIy_abs, 1, 0, dI);
224 dI.convertTo(dI, CV_8U);
228 const float range[] = { 0.f, 256.f };
229 const float *ranges[] = { range };
230 int channels[] = { 0 };
232 int histSize[] = { bins };
234 bool accumulate =
false;
235 cv::calcHist(&dI, 1, channels, cv::Mat(), hist, dims, histSize, ranges, uniform, accumulate);
237 float t =
static_cast<float>(upperThresholdRatio * w * h);
239 for (
int i = 0; i < bins; ++i) {
240 float tf = hist.at<
float>(i);
243 bon =
static_cast<float>(i);
247 float upperThresh = std::max<float>(bon, 1.f);
248 lowerThresh = lowerThresholdRatio * bon;
297 const unsigned int &gaussianFilterSize,
const float &thresholdCanny,
298 const unsigned int &apertureSobel)
300 vpImageFilter::canny(Isrc, Ires, gaussianFilterSize, thresholdCanny / 3.f, thresholdCanny, apertureSobel);
351 const unsigned int &gaussianFilterSize,
352 const float &lowerThreshold,
const float &upperThreshold,
353 const unsigned int &apertureSobel)
355 const float gaussianStdev = 2.f;
356 const float upperThresholdRatio = 0.8f;
357 const float lowerThresholdRatio = 0.6f;
358 #if defined(HAVE_OPENCV_IMGPROC)
364 canny(Isrc, Ires, gaussianFilterSize, lowerThreshold, upperThreshold, apertureSobel,
365 gaussianStdev, lowerThresholdRatio, upperThresholdRatio,
false, cannyBackend, cannyFilteringSteps);
437 const unsigned int &gaussianFilterSize,
438 const float &lowerThreshold,
const float &upperThreshold,
const unsigned int &apertureGradient,
439 const float &gaussianStdev,
const float &lowerThresholdRatio,
const float &upperThresholdRatio,
440 const bool &normalizeGradients,
445 #if defined(HAVE_OPENCV_IMGPROC)
446 cv::Mat img_cvmat, cv_dx, cv_dy, edges_cvmat;
449 gaussianStdev, apertureGradient, cannyFilteringSteps);
450 float upperCannyThresh = upperThreshold;
451 float lowerCannyThresh = lowerThreshold;
452 if (upperCannyThresh < 0.f) {
453 upperCannyThresh =
computeCannyThreshold(img_cvmat, &cv_dx, &cv_dy, lowerCannyThresh, gaussianFilterSize,
454 gaussianStdev, apertureGradient, lowerThresholdRatio, upperThresholdRatio,
455 cannyFilteringSteps);
457 else if (lowerCannyThresh < 0.f) {
458 lowerCannyThresh = upperCannyThresh / 3.f;
460 #if (VISP_HAVE_OPENCV_VERSION >= 0x030200)
461 cv::Canny(cv_dx, cv_dy, edges_cvmat, lowerCannyThresh, upperCannyThresh,
false);
463 cv::GaussianBlur(img_cvmat, img_cvmat, cv::Size((
int)gaussianFilterSize, (
int)gaussianFilterSize),
464 gaussianStdev, gaussianStdev);
465 cv::Canny(img_cvmat, edges_cvmat, lowerCannyThresh, upperCannyThresh);
469 std::string errMsg(
"[vpImageFilter::canny]You asked for CANNY_OPENCV_BACKEND but ViSP has not been compiled with OpenCV");
474 float upperCannyThresh = upperThreshold;
475 float lowerCannyThresh = lowerThreshold;
479 gaussianStdev, apertureGradient, cannyFilteringSteps, cannyBackend, p_mask);
481 if (upperCannyThresh < 0.f) {
482 upperCannyThresh =
computeCannyThreshold(Isrc, lowerCannyThresh, &dIx, &dIy, gaussianFilterSize, gaussianStdev,
483 apertureGradient, lowerThresholdRatio, upperThresholdRatio,
484 cannyFilteringSteps, p_mask);
486 else if (lowerCannyThresh < 0.f) {
487 lowerCannyThresh = upperCannyThresh / 3.f;
489 vpCannyEdgeDetection edgeDetector(gaussianFilterSize, gaussianStdev, apertureGradient, lowerCannyThresh, upperCannyThresh,
490 lowerThresholdRatio, upperThresholdRatio, cannyFilteringSteps);
493 Ires = edgeDetector.
detect(Isrc);
Class that implements the Canny's edge detector. It is possible to use a boolean mask to ignore some ...
vpImage< unsigned char > detect(const vpImage< vpRGBa > &I_color)
Detect the edges in an image. Convert the color image into a gray-scale image.
void setMask(const vpImage< bool > *p_mask)
Set a mask to ignore pixels for which the mask is false.
void setGradients(const vpImage< float > &dIx, const vpImage< float > &dIy)
Set the Gradients of the image that will be processed.
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static std::string vpCannyBackendTypeToString(const vpCannyBackendType &type)
Cast a vpImageFilter::vpCannyBackendTypeToString into a string, to know its name.
static void canny(const vpImage< unsigned char > &I, vpImage< unsigned char > &Ic, const unsigned int &gaussianFilterSize, const float &thresholdCanny, const unsigned int &apertureSobel)
static std::string vpCannyBackendTypeList(const std::string &pref="<", const std::string &sep=" , ", const std::string &suf=">")
Get the list of available vpCannyBackendType.
static std::string vpCannyFiltAndGradTypeToStr(const vpCannyFilteringAndGradientType &type)
Cast a vpImageFilter::vpCannyFilteringAndGradientType into a string, to know its name.
vpCannyFilteringAndGradientType
Canny filter and gradient operators to apply on the image before the edge detection stage.
@ CANNY_GBLUR_SOBEL_FILTERING
Apply Gaussian blur + Sobel operator on the input image.
@ CANNY_GBLUR_SCHARR_FILTERING
Apply Gaussian blur + Scharr operator on the input image.
vpCannyBackendType
Canny filter backends for the edge detection operations.
@ CANNY_VISP_BACKEND
Use ViSP.
@ CANNY_OPENCV_BACKEND
Use OpenCV.
static vpCannyFilteringAndGradientType vpCannyFiltAndGradTypeFromStr(const std::string &name)
Cast a string into a vpImageFilter::vpCannyFilteringAndGradientType.
static float computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_dIx, const cv::Mat *p_cv_dIy, float &lowerThresh, const unsigned int &gaussianKernelSize=5, const float &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const float &lowerThresholdRatio=0.6, const float &upperThresholdRatio=0.8, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING)
Compute the upper Canny edge filter threshold, using Gaussian blur + Sobel or + Scharr operators to c...
static vpCannyBackendType vpCannyBackendTypeFromString(const std::string &name)
Cast a string into a vpImageFilter::vpCannyBackendTypeToString.
static std::string vpGetCannyFiltAndGradTypes(const std::string &pref="<", const std::string &sep=" , ", const std::string &suf=">")
Get the list of available vpCannyFilteringAndGradientType.
static void computePartialDerivatives(const cv::Mat &cv_I, cv::Mat &cv_dIx, cv::Mat &cv_dIy, const bool &computeDx=true, const bool &computeDy=true, const bool &normalize=true, const unsigned int &gaussianKernelSize=5, const float &gaussianStdev=2.f, const unsigned int &apertureGradient=3, const vpCannyFilteringAndGradientType &filteringType=CANNY_GBLUR_SOBEL_FILTERING)
Compute the partial derivatives (i.e. horizontal and vertical gradients) of the input image.