Skip to content

Commit

Permalink
Fix warnings around type conversions and use float in canny() and
Browse files Browse the repository at this point in the history
median() filter
- canny() and median() handle now values in float
  • Loading branch information
fspindle committed Sep 6, 2023
1 parent ec0b314 commit 82ac8da
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 61 deletions.
12 changes: 6 additions & 6 deletions modules/core/include/visp3/core/vpImageFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class VISP_EXPORT vpImageFilter
{
public:
static void canny(const vpImage<unsigned char> &I, vpImage<unsigned char> &Ic, unsigned int gaussianFilterSize,
double thresholdCanny, unsigned int apertureSobel);
float thresholdCanny, unsigned int apertureSobel);

/*!
Apply a 1x3 derivative filter to an image pixel.
Expand Down Expand Up @@ -1222,11 +1222,11 @@ class VISP_EXPORT vpImageFilter
}

#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC)
static double computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, double &lowerThresh);
static double computeCannyThreshold(const vpImage<unsigned char> &I, double &lowerThresh);
static double median(const cv::Mat &cv_I);
static double median(const vpImage<unsigned char> &Isrc);
static std::vector<double> median(const vpImage<vpRGBa> &Isrc);
static float computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, float &lowerThresh);
static float computeCannyThreshold(const vpImage<unsigned char> &I, float &lowerThresh);
static float median(const cv::Mat &cv_I);
static float median(const vpImage<unsigned char> &Isrc);
static std::vector<float> median(const vpImage<vpRGBa> &Isrc);
#endif
};

Expand Down
39 changes: 20 additions & 19 deletions modules/core/src/image/vpImageFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ void vpImageFilter::sepFilter(const vpImage<unsigned char> &I, vpImage<double> &
* The algorithm is based on based on https://github.com/arnaudgelas/OpenCVExamples/blob/master/cvMat/Statistics/Median/Median.cpp
* \param[in] channel : Single channel image in OpenCV format.
*/
double vpImageFilter::median(const cv::Mat &channel)
float vpImageFilter::median(const cv::Mat &channel)
{
double m = (channel.rows * channel.cols) / 2;
float m = (channel.rows * channel.cols) / 2.f;
int bin = 0;
double med = -1.0;
float med = -1.0f;

int histSize = 256;
float range[] = { 0, 256 };
Expand All @@ -165,7 +165,7 @@ double vpImageFilter::median(const cv::Mat &channel)
for (int i = 0; i < histSize && med < 0.0; ++i) {
bin += cvRound(hist.at<float>(i));
if (bin > m && med < 0.0)
med = i;
med = static_cast<float>(i);
}

return med;
Expand All @@ -175,9 +175,10 @@ double vpImageFilter::median(const cv::Mat &channel)
* \brief Calculates the median value of a single channel.
* The algorithm is based on based on https://github.com/arnaudgelas/OpenCVExamples/blob/master/cvMat/Statistics/Median/Median.cpp
* \param[in] Isrc : Gray-level image in ViSP format.
* \return Gray level image median value.
* \sa \ref vpImageFilter::median() "vpImageFilter::median(const cv::Mat)"
*/
double vpImageFilter::median(const vpImage<unsigned char> &Isrc)
float vpImageFilter::median(const vpImage<unsigned char> &Isrc)
{
cv::Mat cv_I;
vpImageConvert::convert(Isrc, cv_I);
Expand All @@ -188,17 +189,17 @@ double vpImageFilter::median(const vpImage<unsigned char> &Isrc)
* \brief Calculates the median value of a vpRGBa image.
* The result is ordered in RGB format.
* \param[in] Isrc : RGB image in ViSP format. Alpha channel is ignored.
* \return std::vector<double> meds such as meds[0] = red-channel-median meds[1] = green-channel-median
* \return std::vector<float> meds such as meds[0] = red-channel-median, meds[1] = green-channel-median
* and meds[2] = blue-channel-median.
* \sa \ref vpImageFilter::median() "vpImageFilter::median(const cv::Mat)"
*/
std::vector<double> vpImageFilter::median(const vpImage<vpRGBa> &Isrc)
std::vector<float> vpImageFilter::median(const vpImage<vpRGBa> &Isrc)
{
cv::Mat cv_I_bgr;
vpImageConvert::convert(Isrc, cv_I_bgr);
std::vector<cv::Mat> channels;
cv::split(cv_I_bgr, channels);
std::vector<double> meds(3);
std::vector<float> meds(3);
const int orderMeds[] = { 2, 1, 0 }; // To keep the order R, G, B
const int orderCvChannels[] = { 0, 1, 2 }; // Because the order of the cv::Mat is B, G, R
for (unsigned int i = 0; i < 3; i++) {
Expand All @@ -213,9 +214,9 @@ std::vector<double> vpImageFilter::median(const vpImage<vpRGBa> &Isrc)
* \param[in] cv_I : The image, in cv format.
* \param[in] p_cv_blur : If different from nullptr, must contain a blurred version of cv_I.
* \param[out] lowerThresh : The lower threshold for the Canny edge filter.
* \return double The upper Canny edge filter threshold.
* \return The upper Canny edge filter threshold.
*/
double vpImageFilter::computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, double &lowerThresh)
float vpImageFilter::computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *p_cv_blur, float &lowerThresh)
{
cv::Mat cv_I_blur;
if (p_cv_blur != nullptr) {
Expand All @@ -232,10 +233,10 @@ double vpImageFilter::computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *
cv::Mat cv_I_scaled_down;
resize(cv_I_blur, cv_I_scaled_down, cv::Size(), scale_down, scale_down, cv::INTER_NEAREST);

double median_pix = vpImageFilter::median(cv_I_scaled_down);
double lower = std::max(0., 0.7 * median_pix);
double upper = std::min(255., 1.3 * median_pix);
upper = std::max(1., upper);
float median_pix = vpImageFilter::median(cv_I_scaled_down);
float lower = std::max(0.f, 0.7f * median_pix);
float upper = std::min(255.f, 1.3f * median_pix);
upper = std::max(1.f, upper);
lowerThresh = lower;
return upper;
}
Expand All @@ -245,9 +246,9 @@ double vpImageFilter::computeCannyThreshold(const cv::Mat &cv_I, const cv::Mat *
*
* \param[in] I : The gray-scale image, in ViSP format.
* \param[in] lowerThresh : Canny lower threshold.
* \return double The upper Canny edge filter threshold.
* \return The upper Canny edge filter threshold.
*/
double vpImageFilter::computeCannyThreshold(const vpImage<unsigned char> &I, double &lowerThresh)
float vpImageFilter::computeCannyThreshold(const vpImage<unsigned char> &I, float &lowerThresh)
{
cv::Mat cv_I;
vpImageConvert::convert(I, cv_I);
Expand Down Expand Up @@ -295,14 +296,14 @@ int main()
\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, double thresholdCanny, unsigned int apertureSobel)
unsigned int gaussianFilterSize, float thresholdCanny, unsigned int apertureSobel)
{
#if defined(HAVE_OPENCV_IMGPROC)
cv::Mat img_cvmat, cv_I_blur, edges_cvmat;
vpImageConvert::convert(Isrc, img_cvmat);
cv::GaussianBlur(img_cvmat, cv_I_blur, cv::Size((int)gaussianFilterSize, (int)gaussianFilterSize), 0, 0);
double upperCannyThresh = thresholdCanny;
double lowerCannyThresh = thresholdCanny / 3.;
float upperCannyThresh = thresholdCanny;
float lowerCannyThresh = thresholdCanny / 3.f;
if (upperCannyThresh < 0) {
upperCannyThresh = computeCannyThreshold(img_cvmat, &cv_I_blur, lowerCannyThresh);
}
Expand Down
22 changes: 11 additions & 11 deletions modules/imgproc/include/visp3/imgproc/vpCircleHoughTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,20 @@ class VISP_EXPORT vpCircleHoughTransform
public:
vpCircleHoughTransformParameters()
: m_gaussianKernelSize(5)
, m_gaussianStdev(1.)
, m_gaussianStdev(1.f)
, m_sobelKernelSize(3)
, m_cannyThresh(-1)
, m_cannyThresh(-1.f)
, m_edgeMapFilteringNbIter(1)
, m_centerXlimits(std::pair<int, int>(std::numeric_limits<int>::min(), std::numeric_limits<int>::max()))
, m_centerYlimits(std::pair<int, int>(std::numeric_limits<int>::min(), std::numeric_limits<int>::max()))
, m_minRadius(0)
, m_maxRadius(1000)
, m_dilatationNbIter(1)
, m_centerThresh(50.)
, m_radiusRatioThresh(2.)
, m_circlePerfectness(0.9)
, m_centerMinDist(15.)
, m_mergingRadiusDiffThresh(1.5 * (float)m_centerMinDist)
, m_centerThresh(50.f)
, m_radiusRatioThresh(2.f)
, m_circlePerfectness(0.9f)
, m_centerMinDist(15.f)
, m_mergingRadiusDiffThresh(1.5f * m_centerMinDist)
{

}
Expand Down Expand Up @@ -532,7 +532,7 @@ class VISP_EXPORT vpCircleHoughTransform
*/
inline void setCircleMinRadius(const float &circle_min_radius)
{
m_algoParams.m_minRadius = circle_min_radius;
m_algoParams.m_minRadius = static_cast<unsigned int>(circle_min_radius);
}

/*!
Expand All @@ -541,7 +541,7 @@ class VISP_EXPORT vpCircleHoughTransform
*/
inline void setCircleMaxRadius(const float &circle_max_radius)
{
m_algoParams.m_maxRadius = circle_max_radius;
m_algoParams.m_maxRadius = static_cast<unsigned int>(circle_max_radius);
}

/*!
Expand Down Expand Up @@ -694,15 +694,15 @@ class VISP_EXPORT vpCircleHoughTransform
/*!
* Get circles min radius in pixels.
*/
inline float getCircleMinRadius() const
inline unsigned int getCircleMinRadius() const
{
return m_algoParams.m_minRadius;
}

/*!
* Get circles max radius in pixels.
*/
inline float getCircleMaxRadius() const
inline unsigned int getCircleMaxRadius() const
{
return m_algoParams.m_maxRadius;
}
Expand Down
38 changes: 19 additions & 19 deletions modules/imgproc/src/vpCircleHoughTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ vpCircleHoughTransform::edgeDetection(const vpImage<unsigned char> &I)
{
#if defined(HAVE_OPENCV_IMGPROC)
float cannyThresh = m_algoParams.m_cannyThresh;
double lowerThresh;
float 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.) {
Expand Down Expand Up @@ -293,7 +293,7 @@ vpCircleHoughTransform::computeCenterCandidates()
int minimumXposition = std::max(m_algoParams.m_centerXlimits.first, -1 * (int)m_algoParams.m_maxRadius);
int maximumXposition = std::min(m_algoParams.m_centerXlimits.second, (int)(m_algoParams.m_maxRadius + nbCols));
minimumXposition = std::min(minimumXposition, maximumXposition - 1);
float minimumXpositionDouble = minimumXposition;
float minimumXpositionFloat = static_cast<float>(minimumXposition);
int offsetX = minimumXposition;
int accumulatorWidth = maximumXposition - minimumXposition + 1;
if (accumulatorWidth <= 0) {
Expand All @@ -307,7 +307,7 @@ vpCircleHoughTransform::computeCenterCandidates()
int minimumYposition = std::max(m_algoParams.m_centerYlimits.first, -1 * (int)m_algoParams.m_maxRadius);
int maximumYposition = std::min(m_algoParams.m_centerYlimits.second, (int)(m_algoParams.m_maxRadius + nbRows));
minimumYposition = std::min(minimumYposition, maximumYposition - 1);
float minimumYpositionDouble = minimumYposition;
float minimumYpositionFloat = static_cast<float>(minimumYposition);
int offsetY = minimumYposition;
int accumulatorHeight = maximumYposition - minimumYposition + 1;
if (accumulatorHeight <= 0) {
Expand Down Expand Up @@ -338,29 +338,29 @@ vpCircleHoughTransform::computeCenterCandidates()
float x1 = (float)c + (float)rad * sx;
float y1 = (float)r + (float)rad * sy;

if (x1 < minimumXpositionDouble || y1 < minimumYpositionDouble) {
if (x1 < minimumXpositionFloat || y1 < minimumYpositionFloat) {
continue; // If either value is lower than maxRadius, it means that the center is outside the search region.
}

int x_low, x_high;
int y_low, y_high;

if (x1 > 0.) {
x_low = std::floor(x1);
x_high = std::ceil(x1);
x_low = static_cast<int>(std::floor(x1));
x_high = static_cast<int>(std::ceil(x1));
}
else {
x_low = -1 * std::ceil(-1. * x1);
x_high = -1 * std::floor(-1. * x1);
x_low = -(static_cast<int>(std::ceil(-x1)));
x_high = -(static_cast<int>(std::floor(-x1)));
}

if (y1 > 0.) {
y_low = std::floor(y1);
y_high = std::ceil(y1);
y_low = static_cast<int>(std::floor(y1));
y_high = static_cast<int>(std::ceil(y1));
}
else {
y_low = -1 * std::ceil(-1. * y1);
y_high = -1 * std::floor(-1. * y1);
y_low = -(static_cast<int>(std::ceil(-1. * y1)));
y_high = -(static_cast<int>(std::floor(-1. * y1)));
}

auto updateAccumulator =
Expand Down Expand Up @@ -441,14 +441,14 @@ void
vpCircleHoughTransform::computeCircleCandidates()
{
size_t nbCenterCandidates = m_centerCandidatesList.size();
unsigned int nbBins = (m_algoParams.m_maxRadius - m_algoParams.m_minRadius + 1)/ m_algoParams.m_centerMinDist;
unsigned int nbBins = static_cast<unsigned int>((m_algoParams.m_maxRadius - m_algoParams.m_minRadius + 1)/ m_algoParams.m_centerMinDist);
nbBins = std::max((unsigned int)1, nbBins); // Avoid having 0 bins, which causes segfault
std::vector<unsigned int> radiusAccumList; /*!< Radius accumulator for each center candidates.*/
std::vector<float> radiusActualValueList; /*!< Vector that contains the actual distance between the edge points and the center candidates.*/

unsigned int rmin2 = m_algoParams.m_minRadius * m_algoParams.m_minRadius;
unsigned int rmax2 = m_algoParams.m_maxRadius * m_algoParams.m_maxRadius;
int circlePerfectness2 = m_algoParams.m_circlePerfectness * m_algoParams.m_circlePerfectness;
unsigned int rmax2 = static_cast<unsigned int>(m_algoParams.m_maxRadius * m_algoParams.m_maxRadius);
int circlePerfectness2 = static_cast<int>(m_algoParams.m_circlePerfectness * m_algoParams.m_circlePerfectness);

for (size_t i = 0; i < nbCenterCandidates; i++) {
std::pair<int, int> centerCandidate = m_centerCandidatesList[i];
Expand All @@ -469,12 +469,12 @@ vpCircleHoughTransform::computeCircleCandidates()
float gy = m_dIy[edgePoint.first][edgePoint.second];
float grad2 = gx * gx + gy * gy;

int scalProd = rx * gx + ry * gy;
int scalProd2 = scalProd * scalProd;
float scalProd = rx * gx + ry * gy;
float scalProd2 = scalProd * scalProd;
if (scalProd2 >= circlePerfectness2 * r2 * grad2) {
// Look for the Radius Candidate Bin RCB_k to which d_ij is "the closest" will have an additionnal vote
float r = std::sqrt(r2);
unsigned int r_bin = std::ceil((r - m_algoParams.m_minRadius)/ m_algoParams.m_centerMinDist);
float r = static_cast<float>(std::sqrt(r2));
unsigned int r_bin = static_cast<unsigned int>(std::ceil((r - m_algoParams.m_minRadius)/ m_algoParams.m_centerMinDist));
r_bin = std::min(r_bin, nbBins - 1);
radiusAccumList[r_bin]++;
radiusActualValueList[r_bin] += r;
Expand Down
6 changes: 3 additions & 3 deletions modules/tracker/me/include/visp3/me/vpMeNurbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ class VISP_EXPORT vpMeNurbs : public vpMeTracker
//! search.
bool enableCannyDetection;
//! First canny threshold
double cannyTh1;
float cannyTh1;
//! Second canny threshold
double cannyTh2;
float cannyTh2;

public:
vpMeNurbs();
Expand Down Expand Up @@ -181,7 +181,7 @@ class VISP_EXPORT vpMeNurbs : public vpMeTracker
\param th1 : The first threshold;
\param th2 : The second threshold;
*/
void setCannyThreshold(double th1, double th2)
void setCannyThreshold(float th1, float th2)
{
this->cannyTh1 = th1;
this->cannyTh2 = th2;
Expand Down
6 changes: 3 additions & 3 deletions modules/tracker/me/src/moving-edges/vpMeNurbs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ vpMeNurbs::vpMeNurbs()
*/
vpMeNurbs::vpMeNurbs(const vpMeNurbs &menurbs)
: vpMeTracker(menurbs), nurbs(menurbs.nurbs), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0),
enableCannyDetection(false), cannyTh1(100.), cannyTh2(200.)
enableCannyDetection(false), cannyTh1(100.f), cannyTh2(200.f)
{
dist = menurbs.dist;
nbControlPoints = menurbs.nbControlPoints;
Expand Down Expand Up @@ -547,8 +547,8 @@ void vpMeNurbs::seekExtremitiesCanny(const vpImage<unsigned char> &I)
std::list<vpImagePoint> ip_edges_list;
if (firstBorder != vpImagePoint(-1, -1)) {
unsigned int dir;
double fi = firstBorder.get_i();
double fj = firstBorder.get_j();
double fi = static_cast<double>(firstBorder.get_i());
double fj = static_cast<double>(firstBorder.get_j());
double w = Isub.getWidth() - 1;
double h = Isub.getHeight() - 1;
// if (firstBorder.get_i() == 0) dir = 4;
Expand Down

0 comments on commit 82ac8da

Please sign in to comment.