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