Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix canny #1287

Merged
merged 5 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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