mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-16 22:35:51 +08:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -33,48 +33,45 @@ public:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
@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, ...);
|
selected, use: `fld_ptr-\>detect(image(roi), lines, ...);
|
||||||
lines += Scalar(roi.x, roi.y, roi.x, roi.y);`
|
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
|
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
|
1 is the start, point 2 - end. Returned lines are directed so that the
|
||||||
brighter side is on their left.
|
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.
|
/** @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.
|
or equal to the image, where the lines were found.
|
||||||
@param lines A vector of the lines that needed to be drawn.
|
@param lines A vector of the lines that needed to be drawn.
|
||||||
@param draw_arrow If true, arrow heads will be drawn.
|
@param draw_arrow If true, arrow heads will be drawn.
|
||||||
*/
|
@param linecolor Line color.
|
||||||
CV_WRAP virtual void drawSegments(InputOutputArray _image, InputArray lines,
|
@param linethickness Line thickness.
|
||||||
bool draw_arrow = false) = 0;
|
*/
|
||||||
|
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() { }
|
virtual ~FastLineDetector() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Creates a smart pointer to a FastLineDetector object and initializes it
|
/** @brief Creates a smart pointer to a FastLineDetector object and initializes it
|
||||||
|
|
||||||
@param _length_threshold 10 - Segment shorter than this will be discarded
|
@param length_threshold Segment shorter than this will be discarded
|
||||||
@param _distance_threshold 1.41421356 - A point placed from a hypothesis line
|
@param distance_threshold A point placed from a hypothesis line
|
||||||
segment farther than this will be
|
segment farther than this will be regarded as an outlier
|
||||||
regarded as an outlier
|
@param canny_th1 First threshold for hysteresis procedure in Canny()
|
||||||
@param _canny_th1 50 - First threshold for
|
@param canny_th2 Second threshold for hysteresis procedure in Canny()
|
||||||
hysteresis procedure in Canny()
|
@param canny_aperture_size Aperturesize for the sobel operator in Canny().
|
||||||
@param _canny_th2 50 - Second threshold for
|
If zero, Canny() is not applied and the input image is taken as an edge image.
|
||||||
hysteresis procedure in Canny()
|
@param do_merge If true, incremental merging of segments will be performed
|
||||||
@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
|
|
||||||
*/
|
*/
|
||||||
CV_EXPORTS_W Ptr<FastLineDetector> createFastLineDetector(
|
CV_EXPORTS_W Ptr<FastLineDetector> createFastLineDetector(
|
||||||
int _length_threshold = 10, float _distance_threshold = 1.414213562f,
|
int length_threshold = 10, float distance_threshold = 1.414213562f,
|
||||||
double _canny_th1 = 50.0, double _canny_th2 = 50.0, int _canny_aperture_size = 3,
|
double canny_th1 = 50.0, double canny_th2 = 50.0, int canny_aperture_size = 3,
|
||||||
bool _do_merge = false);
|
bool do_merge = false);
|
||||||
|
|
||||||
//! @} ximgproc_fast_line_detector
|
//! @} ximgproc_fast_line_detector
|
||||||
}
|
}
|
||||||
|
@@ -391,6 +391,7 @@ void EdgeDrawingImpl::ComputeGradient()
|
|||||||
case SCHARR:
|
case SCHARR:
|
||||||
gx = abs(3 * (com1 + com2) + 10 * (smoothImg[i * width + j + 1] - smoothImg[i * width + j - 1]));
|
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]));
|
gy = abs(3 * (com1 - com2) + 10 * (smoothImg[(i + 1) * width + j] - smoothImg[(i - 1) * width + j]));
|
||||||
|
break;
|
||||||
case LSD:
|
case LSD:
|
||||||
// com1 and com2 differs from previous operators, because LSD has 2x2 kernel
|
// com1 and com2 differs from previous operators, because LSD has 2x2 kernel
|
||||||
com1 = smoothImg[(i + 1) * width + j + 1] - smoothImg[i * width + j];
|
com1 = smoothImg[(i + 1) * width + j + 1] - smoothImg[i * width + j];
|
||||||
@@ -398,6 +399,7 @@ void EdgeDrawingImpl::ComputeGradient()
|
|||||||
|
|
||||||
gx = abs(com1 + com2);
|
gx = abs(com1 + com2);
|
||||||
gy = abs(com1 - com2);
|
gy = abs(com1 - com2);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sum;
|
int sum;
|
||||||
@@ -2943,7 +2945,7 @@ void EdgeDrawingImpl::DetectArcs()
|
|||||||
bm->move(noPixels);
|
bm->move(noPixels);
|
||||||
|
|
||||||
// Try to fit a circle to the entire arc of lines
|
// 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);
|
CircleFit(x, y, noPixels, &xc, &yc, &radius, &circleFitError);
|
||||||
|
|
||||||
double coverage = noPixels / (CV_2PI * radius);
|
double coverage = noPixels / (CV_2PI * radius);
|
||||||
|
@@ -21,46 +21,14 @@ namespace ximgproc{
|
|||||||
class FastLineDetectorImpl : public FastLineDetector
|
class FastLineDetectorImpl : public FastLineDetector
|
||||||
{
|
{
|
||||||
public:
|
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,
|
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,
|
double _canny_th1 = 50.0, double _canny_th2 = 50.0, int _canny_aperture_size = 3,
|
||||||
bool _do_merge = false);
|
bool _do_merge = false);
|
||||||
|
|
||||||
/**
|
void detect(InputArray image, OutputArray lines) CV_OVERRIDE;
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
void drawSegments(InputOutputArray image, InputArray lines, bool draw_arrow = false, Scalar linecolor = Scalar(0, 0, 255), int linethickness = 1) 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;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int imagewidth, imageheight, threshold_length;
|
int imagewidth, imageheight, threshold_length;
|
||||||
@@ -85,25 +53,24 @@ class FastLineDetectorImpl : public FastLineDetector
|
|||||||
|
|
||||||
void lineDetection(const Mat& src, std::vector<SEGMENT>& segments_all);
|
void lineDetection(const Mat& src, std::vector<SEGMENT>& segments_all);
|
||||||
|
|
||||||
void pointInboardTest(const Mat& src, Point2i& pt);
|
void pointInboardTest(const Size srcSize, Point2i& pt);
|
||||||
|
|
||||||
inline void getAngle(SEGMENT& seg);
|
inline void getAngle(SEGMENT& seg);
|
||||||
|
|
||||||
void additionalOperationsOnSegment(const Mat& src, SEGMENT& seg);
|
void additionalOperationsOnSegment(const Mat& src, SEGMENT& seg);
|
||||||
|
|
||||||
void drawSegment(Mat& mat, const SEGMENT& seg, Scalar bgr = Scalar(0,255,0),
|
void drawSegment(InputOutputArray image, const SEGMENT& seg, Scalar bgr = Scalar(0,255,0), int thickness = 1, bool directed = true);
|
||||||
int thickness = 1, bool directed = true);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
CV_EXPORTS Ptr<FastLineDetector> createFastLineDetector(
|
CV_EXPORTS Ptr<FastLineDetector> createFastLineDetector(
|
||||||
int _length_threshold, float _distance_threshold,
|
int length_threshold, float distance_threshold,
|
||||||
double _canny_th1, double _canny_th2, int _canny_aperture_size, bool _do_merge)
|
double canny_th1, double canny_th2, int canny_aperture_size, bool do_merge)
|
||||||
{
|
{
|
||||||
return makePtr<FastLineDetectorImpl>(
|
return makePtr<FastLineDetectorImpl>(
|
||||||
_length_threshold, _distance_threshold,
|
length_threshold, distance_threshold,
|
||||||
_canny_th1, _canny_th2, _canny_aperture_size, _do_merge);
|
canny_th1, canny_th2, canny_aperture_size, do_merge);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -136,30 +103,23 @@ void FastLineDetectorImpl::detect(InputArray _image, OutputArray _lines)
|
|||||||
Mat(lines).copyTo(_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_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 (cn == 1)
|
||||||
if (_image.channels() == 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<Mat> planes;
|
|
||||||
planes.push_back(gray);
|
|
||||||
planes.push_back(gray);
|
|
||||||
planes.push_back(gray);
|
|
||||||
|
|
||||||
merge(planes, _image);
|
|
||||||
|
|
||||||
double gap = 10.0;
|
double gap = 10.0;
|
||||||
double arrow_angle = 30.0;
|
double arrow_angle = 30.0;
|
||||||
|
|
||||||
@@ -172,7 +132,7 @@ void FastLineDetectorImpl::drawSegments(InputOutputArray _image, InputArray line
|
|||||||
const Vec4f& v = _lines.at<Vec4f>(i);
|
const Vec4f& v = _lines.at<Vec4f>(i);
|
||||||
Point2f b(v[0], v[1]);
|
Point2f b(v[0], v[1]);
|
||||||
Point2f e(v[2], v[3]);
|
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)
|
if(draw_arrow)
|
||||||
{
|
{
|
||||||
SEGMENT seg;
|
SEGMENT seg;
|
||||||
@@ -185,8 +145,8 @@ void FastLineDetectorImpl::drawSegments(InputOutputArray _image, InputArray line
|
|||||||
Point2i p1;
|
Point2i p1;
|
||||||
p1.x = cvRound(seg.x2 - gap*cos(arrow_angle * CV_PI / 180.0 + ang));
|
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));
|
p1.y = cvRound(seg.y2 - gap*sin(arrow_angle * CV_PI / 180.0 + ang));
|
||||||
pointInboardTest(_image.getMatRef(), p1);
|
pointInboardTest(image.size(), p1);
|
||||||
line(_image.getMatRef(), Point(cvRound(seg.x2), cvRound(seg.y2)), p1, Scalar(0,0,255), 1);
|
line(image, Point(cvRound(seg.x2), cvRound(seg.y2)), p1, linecolor, linethickness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,10 +437,10 @@ void FastLineDetectorImpl::extractSegments(const std::vector<Point2i>& 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.x = pt.x <= 5 ? 5 : pt.x >= srcSize.width - 5 ? srcSize.width - 5 : pt.x;
|
||||||
pt.y = pt.y <= 5 ? 5 : pt.y >= src.rows - 5 ? src.rows - 5 : pt.y;
|
pt.y = pt.y <= 5 ? 5 : pt.y >= srcSize.height - 5 ? srcSize.height - 5 : pt.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FastLineDetectorImpl::getPointChain(const Mat& img, Point pt,
|
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_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].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));
|
points_left[i].y = cvRound(points[i].y - gap*sin(90.0 * CV_PI / 180.0 + ang));
|
||||||
pointInboardTest(src, points_right[i]);
|
pointInboardTest(src.size(), points_right[i]);
|
||||||
pointInboardTest(src, points_left[i]);
|
pointInboardTest(src.size(), points_left[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iR = 0, iL = 0;
|
int iR = 0, iL = 0;
|
||||||
@@ -717,21 +677,5 @@ void FastLineDetectorImpl::additionalOperationsOnSegment(const Mat& src, SEGMENT
|
|||||||
return;
|
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 cv
|
||||||
} // namespace ximgproc
|
} // namespace ximgproc
|
||||||
|
Reference in New Issue
Block a user