From e59b8f785364c6f6fc8fdb3014f75aa3d42b7202 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 5 Apr 2021 10:43:22 +0000 Subject: [PATCH 1/3] eliminate build warnings --- modules/ximgproc/src/edge_drawing.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/ximgproc/src/edge_drawing.cpp b/modules/ximgproc/src/edge_drawing.cpp index 628893be513..bfabf704ce5 100644 --- a/modules/ximgproc/src/edge_drawing.cpp +++ b/modules/ximgproc/src/edge_drawing.cpp @@ -23,13 +23,13 @@ class EdgeDrawingImpl : public EdgeDrawing }; EdgeDrawingImpl(); - void detectEdges(InputArray src); - void getEdgeImage(OutputArray dst); - void getGradientImage(OutputArray dst); + void detectEdges(InputArray src) CV_OVERRIDE; + void getEdgeImage(OutputArray dst) CV_OVERRIDE; + void getGradientImage(OutputArray dst) CV_OVERRIDE; - vector > getSegments(); - void detectLines(OutputArray lines); - void detectEllipses(OutputArray ellipses); + vector > getSegments() CV_OVERRIDE; + void detectLines(OutputArray lines) CV_OVERRIDE; + void detectEllipses(OutputArray ellipses) CV_OVERRIDE; virtual void read(const FileNode& fn) CV_OVERRIDE; virtual void write(FileStorage& fs) const CV_OVERRIDE; @@ -391,6 +391,7 @@ void EdgeDrawingImpl::ComputeGradient() case SCHARR: gx = abs(3 * (com1 + com2) + 10 * (smoothImg[i * width + j + 1] - smoothImg[i * width + j - 1])); gy = abs(3 * (com1 - com2) + 10 * (smoothImg[(i + 1) * width + j] - smoothImg[(i - 1) * width + j])); + break; case LSD: // com1 and com2 differs from previous operators, because LSD has 2x2 kernel com1 = smoothImg[(i + 1) * width + j + 1] - smoothImg[i * width + j]; @@ -398,6 +399,7 @@ void EdgeDrawingImpl::ComputeGradient() gx = abs(com1 + com2); gy = abs(com1 - com2); + break; } int sum; @@ -2943,7 +2945,7 @@ void EdgeDrawingImpl::DetectArcs() bm->move(noPixels); // Try to fit a circle to the entire arc of lines - double xc, yc, radius, circleFitError; + double xc = -1, yc = -1, radius = -1, circleFitError = -1; CircleFit(x, y, noPixels, &xc, &yc, &radius, &circleFitError); double coverage = noPixels / (CV_2PI * radius); From 930eca198d154799be57c5918ed3d13cefe8f154 Mon Sep 17 00:00:00 2001 From: TT <45615081+tsukada-cs@users.noreply.github.com> Date: Fri, 23 Oct 2020 02:03:11 +0900 Subject: [PATCH 2/3] 3.4/ximgproc: Added edge input feature to fast_line_detector backport of commit: d8197c6ad64468c8b199dcd2343184a51a366f92 --- .../opencv2/ximgproc/fast_line_detector.hpp | 5 ++-- modules/ximgproc/samples/fld_lines.cpp | 5 ++-- modules/ximgproc/src/fast_line_detector.cpp | 23 +++++++++------ modules/ximgproc/test/test_fld.cpp | 28 +++++++++++++++++++ 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp b/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp index 78ec43a61b3..7de0a8ba099 100644 --- a/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp +++ b/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp @@ -65,8 +65,9 @@ class CV_EXPORTS_W FastLineDetector : public Algorithm hysteresis procedure in Canny() @param _canny_th2 50 - Second threshold for hysteresis procedure in Canny() -@param _canny_aperture_size 3 - Aperturesize for the sobel - operator in Canny() +@param _canny_aperture_size 3 - Aperturesize for the sobel operator in Canny(). + If zero, Canny() is not applied and the input + image is taken as an edge image. @param _do_merge false - If true, incremental merging of segments will be performed */ diff --git a/modules/ximgproc/samples/fld_lines.cpp b/modules/ximgproc/samples/fld_lines.cpp index acb4e32ac52..87edf62420d 100644 --- a/modules/ximgproc/samples/fld_lines.cpp +++ b/modules/ximgproc/samples/fld_lines.cpp @@ -37,8 +37,9 @@ int main(int argc, char** argv) // hysteresis procedure in Canny() // canny_th2 50 - Second threshold for // hysteresis procedure in Canny() - // canny_aperture_size 3 - Aperturesize for the sobel - // operator in Canny() + // canny_aperture_size 3 - Aperturesize for the sobel operator in Canny(). + // If zero, Canny() is not applied and the input + // image is taken as an edge image. // do_merge false - If true, incremental merging of segments // will be performed int length_threshold = 10; diff --git a/modules/ximgproc/src/fast_line_detector.cpp b/modules/ximgproc/src/fast_line_detector.cpp index 33560184d2a..4217d9b33c5 100644 --- a/modules/ximgproc/src/fast_line_detector.cpp +++ b/modules/ximgproc/src/fast_line_detector.cpp @@ -29,10 +29,11 @@ class FastLineDetectorImpl : public FastLineDetector * _ hysteresis procedure in Canny() * @param _canny_th2 50 - Second threshold for * _ hysteresis procedure in Canny() - * @param _canny_aperture_size 3 - Aperturesize for the sobel - * _ operator in Canny() + * @param _canny_aperture_size 3 - Aperturesize for the sobel operator in Canny(). + * If zero, Canny() is not applied and the input + * image is taken as an edge image. * @param _do_merge false - If true, incremental merging of segments - will be perfomred + * will be performed */ FastLineDetectorImpl(int _length_threshold = 10, float _distance_threshold = 1.414213562f, double _canny_th1 = 50.0, double _canny_th2 = 50.0, int _canny_aperture_size = 3, @@ -80,7 +81,7 @@ class FastLineDetectorImpl : public FastLineDetector double distPointLine(const Mat& p, Mat& l); - void extractSegments(const std::vector& points, std::vector& segments ); + void extractSegments(const std::vector& points, std::vector& segments); void lineDetection(const Mat& src, std::vector& segments_all); @@ -113,7 +114,7 @@ FastLineDetectorImpl::FastLineDetectorImpl(int _length_threshold, float _distanc canny_th1(_canny_th1), canny_th2(_canny_th2), canny_aperture_size(_canny_aperture_size), do_merge(_do_merge) { CV_Assert(_length_threshold > 0 && _distance_threshold > 0 && - _canny_th1 > 0 && _canny_th2 > 0 && _canny_aperture_size > 0); + _canny_th1 > 0 && _canny_th2 > 0 && _canny_aperture_size >= 0); } void FastLineDetectorImpl::detect(InputArray _image, OutputArray _lines) @@ -344,7 +345,7 @@ template pt = T(pt_tmp); } -void FastLineDetectorImpl::extractSegments(const std::vector& points, std::vector& segments ) +void FastLineDetectorImpl::extractSegments(const std::vector& points, std::vector& segments) { bool is_line; @@ -544,8 +545,14 @@ void FastLineDetectorImpl::lineDetection(const Mat& src, std::vector& s std::vector points; std::vector segments, segments_tmp; Mat canny; - Canny(src, canny, canny_th1, canny_th2, canny_aperture_size); - + if (canny_aperture_size == 0) + { + canny = src; + } + else + { + Canny(src, canny, canny_th1, canny_th2, canny_aperture_size); + } canny.colRange(0,6).rowRange(0,6) = 0; canny.colRange(src.cols-5,src.cols).rowRange(src.rows-5,src.rows) = 0; diff --git a/modules/ximgproc/test/test_fld.cpp b/modules/ximgproc/test/test_fld.cpp index 71f7fd260cd..d2dc8421581 100644 --- a/modules/ximgproc/test/test_fld.cpp +++ b/modules/ximgproc/test/test_fld.cpp @@ -23,6 +23,7 @@ class FLDBase : public testing::Test void GenerateWhiteNoise(Mat& image); void GenerateConstColor(Mat& image); void GenerateLines(Mat& image, const unsigned int numLines); + void GenerateEdgeLines(Mat& image, const unsigned int numLines); void GenerateBrokenLines(Mat& image, const unsigned int numLines); void GenerateRotatedRect(Mat& image); virtual void SetUp(); @@ -55,6 +56,7 @@ void FLDBase::GenerateConstColor(Mat& image) image = Mat(img_size, CV_8UC1, Scalar::all(rng.uniform(0, 256))); } + void FLDBase::GenerateLines(Mat& image, const unsigned int numLines) { image = Mat(img_size, CV_8UC1, Scalar::all(rng.uniform(0, 128))); @@ -68,6 +70,19 @@ void FLDBase::GenerateLines(Mat& image, const unsigned int numLines) } } +void FLDBase::GenerateEdgeLines(Mat& image, const unsigned int numLines) +{ + image = Mat(img_size, CV_8UC1, Scalar::all(0)); + + for(unsigned int i = 0; i < numLines; ++i) + { + int y = rng.uniform(10, img_size.width - 10); + Point p1(y, 10); + Point p2(y, img_size.height - 10); + line(image, p1, p2, Scalar(255), 1); + } +} + void FLDBase::GenerateBrokenLines(Mat& image, const unsigned int numLines) { image = Mat(img_size, CV_8UC1, Scalar::all(rng.uniform(0, 128))); @@ -153,6 +168,19 @@ TEST_F(ximgproc_FLD, lines) ASSERT_EQ(EPOCHS, passedtests); } +TEST_F(ximgproc_FLD, edgeLines) +{ + for (int i = 0; i < EPOCHS; ++i) + { + const unsigned int numOfLines = 1; + GenerateEdgeLines(test_image, numOfLines); + Ptr detector = createFastLineDetector(10, 1.414213562f, 50, 50, 0); + detector->detect(test_image, lines); + if(numOfLines == lines.size()) ++passedtests; + } + ASSERT_EQ(EPOCHS, passedtests); +} + TEST_F(ximgproc_FLD, mergeLines) { for (int i = 0; i < EPOCHS; ++i) From 14b43012da7f6e5cd98c3d6b56476445ee7a5f3f Mon Sep 17 00:00:00 2001 From: Suleyman TURKMEN Date: Wed, 7 Apr 2021 22:15:39 +0300 Subject: [PATCH 3/3] update fast_line_detector.hpp --- .../opencv2/ximgproc/fast_line_detector.hpp | 43 ++++--- modules/ximgproc/src/fast_line_detector.cpp | 108 +++++------------- 2 files changed, 46 insertions(+), 105 deletions(-) diff --git a/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp b/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp index 7de0a8ba099..234cc8a37c2 100644 --- a/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp +++ b/modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp @@ -33,48 +33,45 @@ class CV_EXPORTS_W FastLineDetector : public Algorithm ![image](pics/corridor_fld.jpg) - @param _image A grayscale (CV_8UC1) input image. If only a roi needs to be + @param image A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use: `fld_ptr-\>detect(image(roi), lines, ...); lines += Scalar(roi.x, roi.y, roi.x, roi.y);` - @param _lines A vector of Vec4f elements specifying the beginning + @param lines A vector of Vec4f elements specifying the beginning and ending point of a line. Where Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are directed so that the brighter side is on their left. */ - CV_WRAP virtual void detect(InputArray _image, OutputArray _lines) = 0; + CV_WRAP virtual void detect(InputArray image, OutputArray lines) = 0; /** @brief Draws the line segments on a given image. - @param _image The image, where the lines will be drawn. Should be bigger + @param image The image, where the lines will be drawn. Should be bigger or equal to the image, where the lines were found. @param lines A vector of the lines that needed to be drawn. @param draw_arrow If true, arrow heads will be drawn. - */ - CV_WRAP virtual void drawSegments(InputOutputArray _image, InputArray lines, - bool draw_arrow = false) = 0; + @param linecolor Line color. + @param linethickness Line thickness. + */ + CV_WRAP virtual void drawSegments(InputOutputArray image, InputArray lines, + bool draw_arrow = false, Scalar linecolor = Scalar(0, 0, 255), int linethickness = 1) = 0; virtual ~FastLineDetector() { } }; /** @brief Creates a smart pointer to a FastLineDetector object and initializes it -@param _length_threshold 10 - Segment shorter than this will be discarded -@param _distance_threshold 1.41421356 - A point placed from a hypothesis line - segment farther than this will be - regarded as an outlier -@param _canny_th1 50 - First threshold for - hysteresis procedure in Canny() -@param _canny_th2 50 - Second threshold for - hysteresis procedure in Canny() -@param _canny_aperture_size 3 - Aperturesize for the sobel operator in Canny(). - If zero, Canny() is not applied and the input - image is taken as an edge image. -@param _do_merge false - If true, incremental merging of segments - will be performed +@param length_threshold Segment shorter than this will be discarded +@param distance_threshold A point placed from a hypothesis line + segment farther than this will be regarded as an outlier +@param canny_th1 First threshold for hysteresis procedure in Canny() +@param canny_th2 Second threshold for hysteresis procedure in Canny() +@param canny_aperture_size Aperturesize for the sobel operator in Canny(). + If zero, Canny() is not applied and the input image is taken as an edge image. +@param do_merge If true, incremental merging of segments will be performed */ CV_EXPORTS_W Ptr createFastLineDetector( - int _length_threshold = 10, float _distance_threshold = 1.414213562f, - double _canny_th1 = 50.0, double _canny_th2 = 50.0, int _canny_aperture_size = 3, - bool _do_merge = false); + int length_threshold = 10, float distance_threshold = 1.414213562f, + double canny_th1 = 50.0, double canny_th2 = 50.0, int canny_aperture_size = 3, + bool do_merge = false); //! @} ximgproc_fast_line_detector } diff --git a/modules/ximgproc/src/fast_line_detector.cpp b/modules/ximgproc/src/fast_line_detector.cpp index 4217d9b33c5..4e345b56ee6 100644 --- a/modules/ximgproc/src/fast_line_detector.cpp +++ b/modules/ximgproc/src/fast_line_detector.cpp @@ -21,46 +21,14 @@ namespace ximgproc{ class FastLineDetectorImpl : public FastLineDetector { public: - /** - * @param _length_threshold 10 - Segment shorter than this will be discarded - * @param _distance_threshold 1.41421356 - A point placed from a hypothesis line segment - * farther than this will be regarded as an outlier - * @param _canny_th1 50 - First threshold for - * _ hysteresis procedure in Canny() - * @param _canny_th2 50 - Second threshold for - * _ hysteresis procedure in Canny() - * @param _canny_aperture_size 3 - Aperturesize for the sobel operator in Canny(). - * If zero, Canny() is not applied and the input - * image is taken as an edge image. - * @param _do_merge false - If true, incremental merging of segments - * will be performed - */ + FastLineDetectorImpl(int _length_threshold = 10, float _distance_threshold = 1.414213562f, double _canny_th1 = 50.0, double _canny_th2 = 50.0, int _canny_aperture_size = 3, bool _do_merge = false); - /** - * Detect lines in the input image. - * - * @param _image A grayscale(CV_8UC1) input image. - * If only a roi needs to be selected, use - * lsd_ptr->detect(image(roi), ..., lines); - * lines += Scalar(roi.x, roi.y, roi.x, roi.y); - * @param _lines Return: A vector of Vec4f elements specifying the beginning and ending point of - * a line. Where Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 is the end. - * Returned lines are directed so that the brighter side is placed on left. - */ - void detect(InputArray _image, OutputArray _lines) CV_OVERRIDE; - - /** - * Draw lines on the given canvas. - * - * @param image The image, where lines will be drawn - * Should have the size of the image, where the lines were found - * @param lines The lines that need to be drawn - * @param draw_arrow If true, arrow heads will be drawn - */ - void drawSegments(InputOutputArray _image, InputArray lines, bool draw_arrow = false) CV_OVERRIDE; + void detect(InputArray image, OutputArray lines) CV_OVERRIDE; + + void drawSegments(InputOutputArray image, InputArray lines, bool draw_arrow = false, Scalar linecolor = Scalar(0, 0, 255), int linethickness = 1) CV_OVERRIDE; private: int imagewidth, imageheight, threshold_length; @@ -85,25 +53,24 @@ class FastLineDetectorImpl : public FastLineDetector void lineDetection(const Mat& src, std::vector& segments_all); - void pointInboardTest(const Mat& src, Point2i& pt); + void pointInboardTest(const Size srcSize, Point2i& pt); inline void getAngle(SEGMENT& seg); void additionalOperationsOnSegment(const Mat& src, SEGMENT& seg); - void drawSegment(Mat& mat, const SEGMENT& seg, Scalar bgr = Scalar(0,255,0), - int thickness = 1, bool directed = true); + void drawSegment(InputOutputArray image, const SEGMENT& seg, Scalar bgr = Scalar(0,255,0), int thickness = 1, bool directed = true); }; ///////////////////////////////////////////////////////////////////////////////////////// CV_EXPORTS Ptr createFastLineDetector( - int _length_threshold, float _distance_threshold, - double _canny_th1, double _canny_th2, int _canny_aperture_size, bool _do_merge) + int length_threshold, float distance_threshold, + double canny_th1, double canny_th2, int canny_aperture_size, bool do_merge) { return makePtr( - _length_threshold, _distance_threshold, - _canny_th1, _canny_th2, _canny_aperture_size, _do_merge); + length_threshold, distance_threshold, + canny_th1, canny_th2, canny_aperture_size, do_merge); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -136,30 +103,23 @@ void FastLineDetectorImpl::detect(InputArray _image, OutputArray _lines) Mat(lines).copyTo(_lines); } -void FastLineDetectorImpl::drawSegments(InputOutputArray _image, InputArray lines, bool draw_arrow) +void FastLineDetectorImpl::drawSegments(InputOutputArray image, InputArray lines, bool draw_arrow, Scalar linecolor, int linethickness) { CV_INSTRUMENT_REGION(); - CV_Assert(!_image.empty() && (_image.channels() == 1 || _image.channels() == 3)); + int cn = image.channels(); + CV_Assert(!image.empty() && ( cn == 1 || cn == 3 || cn == 4)); - Mat gray; - if (_image.channels() == 1) + if (cn == 1) { - gray = _image.getMatRef(); + cvtColor(image, image, COLOR_GRAY2BGR); } - else if (_image.channels() == 3) + else { - cvtColor(_image, gray, COLOR_BGR2GRAY); + cvtColor(image, image, COLOR_BGRA2GRAY); + cvtColor(image, image, cn == 3 ? COLOR_GRAY2BGR : COLOR_GRAY2BGRA); } - // Create a 3 channel image in order to draw colored lines - std::vector planes; - planes.push_back(gray); - planes.push_back(gray); - planes.push_back(gray); - - merge(planes, _image); - double gap = 10.0; double arrow_angle = 30.0; @@ -172,7 +132,7 @@ void FastLineDetectorImpl::drawSegments(InputOutputArray _image, InputArray line const Vec4f& v = _lines.at(i); Point2f b(v[0], v[1]); Point2f e(v[2], v[3]); - line(_image.getMatRef(), b, e, Scalar(0, 0, 255), 1); + line(image, b, e, linecolor, linethickness); if(draw_arrow) { SEGMENT seg; @@ -185,8 +145,8 @@ void FastLineDetectorImpl::drawSegments(InputOutputArray _image, InputArray line Point2i p1; p1.x = cvRound(seg.x2 - gap*cos(arrow_angle * CV_PI / 180.0 + ang)); p1.y = cvRound(seg.y2 - gap*sin(arrow_angle * CV_PI / 180.0 + ang)); - pointInboardTest(_image.getMatRef(), p1); - line(_image.getMatRef(), Point(cvRound(seg.x2), cvRound(seg.y2)), p1, Scalar(0,0,255), 1); + pointInboardTest(image.size(), p1); + line(image, Point(cvRound(seg.x2), cvRound(seg.y2)), p1, linecolor, linethickness); } } } @@ -477,10 +437,10 @@ void FastLineDetectorImpl::extractSegments(const std::vector& points, s } } -void FastLineDetectorImpl::pointInboardTest(const Mat& src, Point2i& pt) +void FastLineDetectorImpl::pointInboardTest(const Size srcSize, Point2i& pt) { - pt.x = pt.x <= 5 ? 5 : pt.x >= src.cols - 5 ? src.cols - 5 : pt.x; - pt.y = pt.y <= 5 ? 5 : pt.y >= src.rows - 5 ? src.rows - 5 : pt.y; + pt.x = pt.x <= 5 ? 5 : pt.x >= srcSize.width - 5 ? srcSize.width - 5 : pt.x; + pt.y = pt.y <= 5 ? 5 : pt.y >= srcSize.height - 5 ? srcSize.height - 5 : pt.y; } bool FastLineDetectorImpl::getPointChain(const Mat& img, Point pt, @@ -692,8 +652,8 @@ void FastLineDetectorImpl::additionalOperationsOnSegment(const Mat& src, SEGMENT points_right[i].y = cvRound(points[i].y + gap*sin(90.0 * CV_PI / 180.0 + ang)); points_left[i].x = cvRound(points[i].x - gap*cos(90.0 * CV_PI / 180.0 + ang)); points_left[i].y = cvRound(points[i].y - gap*sin(90.0 * CV_PI / 180.0 + ang)); - pointInboardTest(src, points_right[i]); - pointInboardTest(src, points_left[i]); + pointInboardTest(src.size(), points_right[i]); + pointInboardTest(src.size(), points_left[i]); } int iR = 0, iL = 0; @@ -717,21 +677,5 @@ void FastLineDetectorImpl::additionalOperationsOnSegment(const Mat& src, SEGMENT return; } -void FastLineDetectorImpl::drawSegment(Mat& mat, const SEGMENT& seg, Scalar bgr, int thickness, bool directed) -{ - double gap = 10.0; - double ang = (double)seg.angle; - double arrow_angle = 30.0; - - Point2i p1; - p1.x = cvRound(seg.x2 - gap*cos(arrow_angle * CV_PI / 180.0 + ang)); - p1.y = cvRound(seg.y2 - gap*sin(arrow_angle * CV_PI / 180.0 + ang)); - pointInboardTest(mat, p1); - - line(mat, Point(cvRound(seg.x1), cvRound(seg.y1)), - Point(cvRound(seg.x2), cvRound(seg.y2)), bgr, thickness, 1); - if(directed) - line(mat, Point(cvRound(seg.x2), cvRound(seg.y2)), p1, bgr, thickness, 1); -} } // namespace cv } // namespace ximgproc