diff --git a/modules/imgproc/src/lsd.cpp b/modules/imgproc/src/lsd.cpp index b28403f268..969d617caf 100644 --- a/modules/imgproc/src/lsd.cpp +++ b/modules/imgproc/src/lsd.cpp @@ -314,31 +314,29 @@ private: * * @param s Starting point for the region. * @param reg Return: Vector of points, that are part of the region - * @param reg_size Return: The size of the region. * @param reg_angle Return: The mean angle of the region. * @param prec The precision by which each region angle should be aligned to the mean. */ void region_grow(const Point2i& s, std::vector& reg, - int& reg_size, double& reg_angle, const double& prec); + double& reg_angle, const double& prec); /** * Finds the bounding rotated rectangle of a region. * * @param reg The region of points, from which the rectangle to be constructed from. - * @param reg_size The number of points in the region. * @param reg_angle The mean angle of the region. * @param prec The precision by which points were found. * @param p Probability of a point with angle within 'prec'. * @param rec Return: The generated rectangle. */ - void region2rect(const std::vector& reg, const int reg_size, const double reg_angle, + void region2rect(const std::vector& reg, const double reg_angle, const double prec, const double p, rect& rec) const; /** * Compute region's angle as the principal inertia axis of the region. * @return Regions angle. */ - double get_theta(const std::vector& reg, const int& reg_size, const double& x, + double get_theta(const std::vector& reg, const double& x, const double& y, const double& reg_angle, const double& prec) const; /** @@ -347,14 +345,14 @@ private: * estimated angle tolerance. If this fails to produce a rectangle with the right density of region points, * 'reduce_region_radius' is called to try to satisfy this condition. */ - bool refine(std::vector& reg, int& reg_size, double reg_angle, + bool refine(std::vector& reg, double reg_angle, const double prec, double p, rect& rec, const double& density_th); /** * Reduce the region size, by elimination the points far from the starting point, until that leads to * rectangle with the right density of region points or to discard the region if too small. */ - bool reduce_region_radius(std::vector& reg, int& reg_size, double reg_angle, + bool reduce_region_radius(std::vector& reg, double reg_angle, const double prec, double p, rect& rec, double density, const double& density_th); /** @@ -460,12 +458,12 @@ void LineSegmentDetectorImpl::flsd(std::vector& lines, } LOG_NT = 5 * (log10(double(img_width)) + log10(double(img_height))) / 2 + log10(11.0); - const int min_reg_size = int(-LOG_NT/log10(p)); // minimal number of points in region that can give a meaningful event + const size_t min_reg_size = size_t(-LOG_NT/log10(p)); // minimal number of points in region that can give a meaningful event // // Initialize region only when needed // Mat region = Mat::zeros(scaled_image.size(), CV_8UC1); used = Mat_::zeros(scaled_image.size()); // zeros = NOTUSED - std::vector reg(img_width * img_height); + std::vector reg; // Search for line segments for(size_t i = 0, list_size = list.size(); i < list_size; ++i) @@ -473,22 +471,21 @@ void LineSegmentDetectorImpl::flsd(std::vector& lines, const Point2i& point = list[i].p; if((used.at(point) == NOTUSED) && (angles.at(point) != NOTDEF)) { - int reg_size; double reg_angle; - region_grow(list[i].p, reg, reg_size, reg_angle, prec); + region_grow(list[i].p, reg, reg_angle, prec); // Ignore small regions - if(reg_size < min_reg_size) { continue; } + if(reg.size() < min_reg_size) { continue; } // Construct rectangular approximation for the region rect rec; - region2rect(reg, reg_size, reg_angle, prec, p, rec); + region2rect(reg, reg_angle, prec, p, rec); double log_nfa = -1; if(doRefine > LSD_REFINE_NONE) { // At least REFINE_STANDARD lvl. - if(!refine(reg, reg_size, reg_angle, prec, p, rec, DENSITY_TH)) { continue; } + if(!refine(reg, reg_angle, prec, p, rec, DENSITY_TH)) { continue; } if(doRefine >= LSD_REFINE_ADV) { @@ -616,23 +613,26 @@ void LineSegmentDetectorImpl::ll_angle(const double& threshold, } void LineSegmentDetectorImpl::region_grow(const Point2i& s, std::vector& reg, - int& reg_size, double& reg_angle, const double& prec) + double& reg_angle, const double& prec) { + reg.clear(); + // Point to this region - reg_size = 1; - reg[0].x = s.x; - reg[0].y = s.y; - reg[0].used = &used.at(s); + RegionPoint seed; + seed.x = s.x; + seed.y = s.y; + seed.used = &used.at(s); reg_angle = angles.at(s); - reg[0].angle = reg_angle; - reg[0].modgrad = modgrad.at(s); + seed.angle = reg_angle; + seed.modgrad = modgrad.at(s); + reg.push_back(seed); float sumdx = float(std::cos(reg_angle)); float sumdy = float(std::sin(reg_angle)); - *reg[0].used = USED; + *seed.used = USED; //Try neighboring regions - for(int i = 0; i < reg_size; ++i) + for (size_t i = 0;i& reg, const int reg_size, +void LineSegmentDetectorImpl::region2rect(const std::vector& reg, const double reg_angle, const double prec, const double p, rect& rec) const { double x = 0, y = 0, sum = 0; - for(int i = 0; i < reg_size; ++i) + for(size_t i = 0; i < reg.size(); ++i) { const RegionPoint& pnt = reg[i]; const double& weight = pnt.modgrad; @@ -689,14 +689,14 @@ void LineSegmentDetectorImpl::region2rect(const std::vector& reg, c x /= sum; y /= sum; - double theta = get_theta(reg, reg_size, x, y, reg_angle, prec); + double theta = get_theta(reg, x, y, reg_angle, prec); // Find length and width double dx = cos(theta); double dy = sin(theta); double l_min = 0, l_max = 0, w_min = 0, w_max = 0; - for(int i = 0; i < reg_size; ++i) + for(size_t i = 0; i < reg.size(); ++i) { double regdx = double(reg[i].x) - x; double regdy = double(reg[i].y) - y; @@ -728,7 +728,7 @@ void LineSegmentDetectorImpl::region2rect(const std::vector& reg, c if(rec.width < 1.0) rec.width = 1.0; } -double LineSegmentDetectorImpl::get_theta(const std::vector& reg, const int& reg_size, const double& x, +double LineSegmentDetectorImpl::get_theta(const std::vector& reg, const double& x, const double& y, const double& reg_angle, const double& prec) const { double Ixx = 0.0; @@ -736,7 +736,7 @@ double LineSegmentDetectorImpl::get_theta(const std::vector& reg, c double Ixy = 0.0; // Compute inertia matrix - for(int i = 0; i < reg_size; ++i) + for(size_t i = 0; i < reg.size(); ++i) { const double& regx = reg[i].x; const double& regy = reg[i].y; @@ -766,10 +766,10 @@ double LineSegmentDetectorImpl::get_theta(const std::vector& reg, c return theta; } -bool LineSegmentDetectorImpl::refine(std::vector& reg, int& reg_size, double reg_angle, +bool LineSegmentDetectorImpl::refine(std::vector& reg, double reg_angle, const double prec, double p, rect& rec, const double& density_th) { - double density = double(reg_size) / (dist(rec.x1, rec.y1, rec.x2, rec.y2) * rec.width); + double density = double(reg.size()) / (dist(rec.x1, rec.y1, rec.x2, rec.y2) * rec.width); if (density >= density_th) { return true; } @@ -780,7 +780,7 @@ bool LineSegmentDetectorImpl::refine(std::vector& reg, int& reg_siz double sum = 0, s_sum = 0; int n = 0; - for (int i = 0; i < reg_size; ++i) + for (size_t i = 0; i < reg.size(); ++i) { *(reg[i].used) = NOTUSED; if (dist(xc, yc, reg[i].x, reg[i].y) < rec.width) @@ -797,16 +797,16 @@ bool LineSegmentDetectorImpl::refine(std::vector& reg, int& reg_siz double tau = 2.0 * sqrt((s_sum - 2.0 * mean_angle * sum) / double(n) + mean_angle * mean_angle); // Try new region - region_grow(Point(reg[0].x, reg[0].y), reg, reg_size, reg_angle, tau); + region_grow(Point(reg[0].x, reg[0].y), reg, reg_angle, tau); - if (reg_size < 2) { return false; } + if (reg.size() < 2) { return false; } - region2rect(reg, reg_size, reg_angle, prec, p, rec); - density = double(reg_size) / (dist(rec.x1, rec.y1, rec.x2, rec.y2) * rec.width); + region2rect(reg, reg_angle, prec, p, rec); + density = double(reg.size()) / (dist(rec.x1, rec.y1, rec.x2, rec.y2) * rec.width); if (density < density_th) { - return reduce_region_radius(reg, reg_size, reg_angle, prec, p, rec, density, density_th); + return reduce_region_radius(reg, reg_angle, prec, p, rec, density, density_th); } else { @@ -814,7 +814,7 @@ bool LineSegmentDetectorImpl::refine(std::vector& reg, int& reg_siz } } -bool LineSegmentDetectorImpl::reduce_region_radius(std::vector& reg, int& reg_size, double reg_angle, +bool LineSegmentDetectorImpl::reduce_region_radius(std::vector& reg, double reg_angle, const double prec, double p, rect& rec, double density, const double& density_th) { // Compute region's radius @@ -828,25 +828,25 @@ bool LineSegmentDetectorImpl::reduce_region_radius(std::vector& reg { radSq *= 0.75*0.75; // Reduce region's radius to 75% of its value // Remove points from the region and update 'used' map - for(int i = 0; i < reg_size; ++i) + for (size_t i = 0; i < reg.size(); ++i) { if(distSq(xc, yc, double(reg[i].x), double(reg[i].y)) > radSq) { // Remove point from the region *(reg[i].used) = NOTUSED; - std::swap(reg[i], reg[reg_size - 1]); - --reg_size; + std::swap(reg[i], reg[reg.size() - 1]); + reg.pop_back(); --i; // To avoid skipping one point } } - if(reg_size < 2) { return false; } + if(reg.size() < 2) { return false; } // Re-compute rectangle - region2rect(reg, reg_size ,reg_angle, prec, p, rec); + region2rect(reg ,reg_angle, prec, p, rec); // Re-compute region points density - density = double(reg_size) / + density = double(reg.size()) / (dist(rec.x1, rec.y1, rec.x2, rec.y2) * rec.width); }