Skip to content

Commit

Permalink
Merge pull request #1287 from rolalaro/fixCanny
Browse files Browse the repository at this point in the history
Fix canny
  • Loading branch information
fspindle authored Dec 1, 2023
2 parents e49493a + e459437 commit e4338fe
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 23 deletions.
46 changes: 27 additions & 19 deletions modules/core/src/image/vpCannyEdgeDetection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ vpCannyEdgeDetection::performFilteringAndGradientComputation(const vpImage<unsig
/**
* \brief Get the interpolation weights and offsets.
*
* \param[in] absoluteTheta : The absolute value of the angle of the edge, expressed in degrees.
* \param[in] gradientOrientation : The positive value of the angle of the edge, expressed in radians.
* Its value is between 0 and M_PIf radians.
* \param[out] alpha : The weight of the first point used for the interpolation.
* \param[out] beta : The weight of the second point used for the interpolation.
* \param[out] dRowGradAlpha : The offset along the row attached to the alpha weight.
Expand All @@ -244,45 +245,45 @@ vpCannyEdgeDetection::performFilteringAndGradientComputation(const vpImage<unsig
* \param[out] dColGradBeta : The offset along the column attached to the beta weight.
*/
void
getInterpolationWeightsAndOffsets(const float &absoluteTheta,
getInterpolationWeightsAndOffsets(const float &gradientOrientation,
float &alpha, float &beta,
int &dRowGradAlpha, int &dRowGradBeta,
int &dColGradAlpha, int &dColGradBeta
)
{
float thetaMin = 0.f;
if (absoluteTheta < 45.f) {
if (gradientOrientation < M_PI_4f) {
// Angles between 0 and 45 deg rely on the horizontal and diagonal points
dColGradAlpha = 1;
dColGradBeta = 1;
dRowGradAlpha = 0;
dRowGradBeta = -1;
}
else if (absoluteTheta >= 45.f && absoluteTheta < 90.f) {
else if (gradientOrientation >= M_PI_4f && gradientOrientation < M_PI_2f) {
// Angles between 45 and 90 deg rely on the diagonal and vertical points
thetaMin = 45.f;
thetaMin = M_PI_4f;
dColGradAlpha = 1;
dColGradBeta = 0;
dRowGradAlpha = -1;
dRowGradBeta = -1;
}
else if (absoluteTheta >= 90.f && absoluteTheta < 135.f) {
else if (gradientOrientation >= M_PI_2f && gradientOrientation < (3.f * M_PI_4f)) {
// Angles between 90 and 135 deg rely on the vertical and diagonal points
thetaMin = 90.f;
thetaMin = M_PI_2f;
dColGradAlpha = 0;
dColGradBeta = -1;
dRowGradAlpha = -1;
dRowGradBeta = -1;
}
else if (absoluteTheta >= 135.f && absoluteTheta < 180.f) {
else if (gradientOrientation >= (3.f * M_PI_4f) && gradientOrientation < M_PIf) {
// Angles between 135 and 180 deg rely on the vertical and diagonal points
thetaMin = 135.f;
thetaMin = 3.f * M_PI_4f;
dColGradAlpha = -1;
dColGradBeta = -1;
dRowGradAlpha = -1;
dRowGradBeta = 0;
}
beta = (absoluteTheta - thetaMin) / 45.f;
beta = (gradientOrientation - thetaMin) / M_PI_4f;
alpha = 1.f - beta;
}

Expand Down Expand Up @@ -314,28 +315,35 @@ getManhattanGradient(const vpImage<float> &dIx, const vpImage<float> &dIy, const
}

/**
* @brief Get the absolute value of the gradient orientation.
* @brief Get the gradient orientation, expressed in radians, between 0 and M_PIf radians.
* If the gradient orientation is negative, we add M_PI radians in
* order to keep the same orientation but in the positive direction.
*
* @param dIx : Gradient along the horizontal axis.
* @param dIy : Gradient along the vertical axis.
* @param row : Index along the vertical axis.
* @param col : Index along the horizontal axis.
* @return float The absolute value of the gradient orientation, expressed in degrees.
* @return float The positive value of the gradient orientation, expressed in radians.
*/
float
getAbsoluteTheta(const vpImage<float> &dIx, const vpImage<float> &dIy, const int &row, const int &col)
getGradientOrientation(const vpImage<float> &dIx, const vpImage<float> &dIy, const int &row, const int &col)
{
float absoluteTheta = 0.f;
float gradientOrientation = 0.f;
float dx = dIx[row][col];
float dy = dIy[row][col];

if (std::abs(dx) < std::numeric_limits<float>::epsilon()) {
absoluteTheta = 90.f;
gradientOrientation = M_PI_2f;
}
else {
absoluteTheta = static_cast<float>(vpMath::deg(std::abs(std::atan2(dy, dx))));
// -dy because the y-axis of the image is oriented towards the bottom of the screen
// while we later work with a y-axis oriented towards the top when getting the theta quadrant.
gradientOrientation = static_cast<float>(std::atan2(-dy , dx));
if(gradientOrientation < 0.f) {
gradientOrientation += M_PIf; // + M_PI in order to be between 0 and M_PIf
}
}
return absoluteTheta;
return gradientOrientation;
}

void
Expand All @@ -358,9 +366,9 @@ vpCannyEdgeDetection::performEdgeThinning(const float &lowerThreshold)
// depending on the gradient orientation
int dRowAlphaPlus = 0, dRowBetaPlus = 0;
int dColAphaPlus = 0, dColBetaPlus = 0;
float absTheta = getAbsoluteTheta(m_dIx, m_dIy, row, col);
float gradientOrientation = getGradientOrientation(m_dIx, m_dIy, row, col);
float alpha = 0.f, beta = 0.f;
getInterpolationWeightsAndOffsets(absTheta, alpha, beta, dRowAlphaPlus, dRowBetaPlus, dColAphaPlus, dColBetaPlus);
getInterpolationWeightsAndOffsets(gradientOrientation, alpha, beta, dRowAlphaPlus, dRowBetaPlus, dColAphaPlus, dColBetaPlus);
int dRowAlphaMinus = -dRowAlphaPlus, dRowBetaMinus = -dRowBetaPlus;
int dColAphaMinus = -dColAphaPlus, dColBetaMinus = -dColBetaPlus;
float gradAlphaPlus = getManhattanGradient(m_dIx, m_dIy, row + dRowAlphaPlus, col + dColAphaPlus);
Expand Down
8 changes: 4 additions & 4 deletions modules/core/src/image/vpImageFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ float vpImageFilter::computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p
const float range[] = { 0.f, 256.f }; // The upper boundary is exclusive
const float *ranges[] = { range };
int channels[] = { 0 };
bool dims = 1; // The number of dimensions of the histogram
int dims = 1; // The number of dimensions of the histogram
int histSize[] = { bins };
bool uniform = true;
bool accumulate = false; // Clear the histogram at the beginning of calcHist if false, does not clear it otherwise
Expand Down Expand Up @@ -741,14 +741,14 @@ void vpImageFilter::computePartialDerivatives(const cv::Mat &cv_I,
if (normalize) {
scale = 1. / 8.;
if (apertureGradient > 3) {
scale *= std::pow(1./16., ((apertureGradient -1.)/2.) - 1.);
scale *= std::pow(1./2., (apertureGradient * 2. - 3.)); // 1 / 2^(2 x ksize - dx - dy -2) with ksize =apertureGradient and dx xor dy = 1
}
}
if (computeDx) {
cv::Sobel(img_blur, cv_dIx, CV_16S, 1, 0, apertureGradient, 1, 0, scale);
cv::Sobel(img_blur, cv_dIx, CV_16S, 1, 0, apertureGradient, scale, 0., cv::BORDER_REPLICATE);
}
if (computeDy) {
cv::Sobel(img_blur, cv_dIy, CV_16S, 0, 1, apertureGradient, 1, 0, scale);
cv::Sobel(img_blur, cv_dIy, CV_16S, 0, 1, apertureGradient, scale, 0., cv::BORDER_REPLICATE);
}
}
else if (filteringType == vpImageFilter::CANNY_GBLUR_SCHARR_FILTERING) {
Expand Down

0 comments on commit e4338fe

Please sign in to comment.