Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
a2582d43
Commit
a2582d43
authored
Dec 12, 2016
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #892 from spacetrain:fast_line_detector
parents
fa8839bb
a7dada15
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1092 additions
and
7 deletions
+1092
-7
corridor_fld.jpg
modules/ximgproc/doc/pics/corridor_fld.jpg
+0
-0
ximgproc.bib
modules/ximgproc/doc/ximgproc.bib
+9
-0
ximgproc.hpp
modules/ximgproc/include/opencv2/ximgproc.hpp
+8
-7
fast_line_detector.hpp
.../ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp
+81
-0
fld_lines.cpp
modules/ximgproc/samples/fld_lines.cpp
+91
-0
fast_line_detector.cpp
modules/ximgproc/src/fast_line_detector.cpp
+730
-0
test_fld.cpp
modules/ximgproc/test/test_fld.cpp
+173
-0
corridor.jpg
samples/data/corridor.jpg
+0
-0
No files found.
modules/ximgproc/doc/pics/corridor_fld.jpg
0 → 100644
View file @
a2582d43
517 KB
modules/ximgproc/doc/ximgproc.bib
View file @
a2582d43
...
...
@@ -47,6 +47,15 @@
publisher={Springer}
}
@inproceedings{Lee14,
title={Outdoor place recognition in urban environments using straight lines},
author={Lee, Jin Han and Lee, Sehyung and Zhang, Guoxuan and Lim, Jongwoo and Chung, Wan Kyun and Suh, Il Hong},
booktitle={2014 IEEE International Conference on Robotics and Automation (ICRA)},
pages={5550--5557},
year={2014},
organization={IEEE}
}
@inproceedings{Lim2013,
title={Sketch tokens: A learned mid-level representation for contour and object detection},
author={Lim, Joseph J and Zitnick, C Lawrence and Doll{\'a}r, Piotr},
...
...
modules/ximgproc/include/opencv2/ximgproc.hpp
View file @
a2582d43
...
...
@@ -2,26 +2,26 @@
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
*
*
*
* License Agreement
* For Open Source Computer Vision Library
* (3 - clause BSD License)
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met :
*
*
* *Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution.
*
*
* * Neither the names of the copyright holders nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* This software is provided by the copyright holders and contributors "as is" and
* any express or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose are disclaimed.
...
...
@@ -49,6 +49,7 @@
#include "ximgproc/slic.hpp"
#include "ximgproc/lsc.hpp"
#include "ximgproc/paillou_filter.hpp"
#include "ximgproc/fast_line_detector.hpp"
/** @defgroup ximgproc Extended Image Processing
...
...
modules/ximgproc/include/opencv2/ximgproc/fast_line_detector.hpp
0 → 100644
View file @
a2582d43
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_FAST_LINE_DETECTOR_HPP__
#define __OPENCV_FAST_LINE_DETECTOR_HPP__
#include <opencv2/core.hpp>
namespace
cv
{
namespace
ximgproc
{
//! @addtogroup ximgproc_feature
//! @{
/** @brief Class implementing the FLD (Fast Line Detector) algorithm described
in @cite Lee14 .
*/
//! @include samples/fld_lines.cpp
class
CV_EXPORTS_W
FastLineDetector
:
public
Algorithm
{
public
:
/** @example fld_lines.cpp
An example using the FastLineDetector
*/
/** @brief Finds lines in the input image.
This is the output of the default parameters of the algorithm on the above
shown image.
![image](pics/corridor_fld.jpg)
@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
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
;
/** @brief Draws the line segments on a given image.
@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
;
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()
@param _do_merge false - If true, incremental merging of segments
will be perfomred
*/
CV_EXPORTS_W
Ptr
<
FastLineDetector
>
createFastLineDetector
(
int
_length_threshold
=
10
,
float
_distance_threshold
=
1.414213562
f
,
double
_canny_th1
=
50.0
,
double
_canny_th2
=
50.0
,
int
_canny_aperture_size
=
3
,
bool
_do_merge
=
false
);
//! @} ximgproc_feature
}
}
#endif
modules/ximgproc/samples/fld_lines.cpp
0 → 100644
View file @
a2582d43
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
::
ximgproc
;
int
main
(
int
argc
,
char
**
argv
)
{
std
::
string
in
;
cv
::
CommandLineParser
parser
(
argc
,
argv
,
"{@input|../samples/data/corridor.jpg|input image}{help h||show help message}"
);
if
(
parser
.
has
(
"help"
))
{
parser
.
printMessage
();
return
0
;
}
in
=
parser
.
get
<
string
>
(
"@input"
);
Mat
image
=
imread
(
in
,
IMREAD_GRAYSCALE
);
if
(
image
.
empty
()
)
{
return
-
1
;
}
// Create LSD detector
Ptr
<
LineSegmentDetector
>
lsd
=
createLineSegmentDetector
();
vector
<
Vec4f
>
lines_lsd
;
// Create FLD detector
// Param Default value Description
// length_threshold 10 - Segments shorter than this will be discarded
// distance_threshold 1.41421356 - A point placed from a hypothesis line
// segment farther than this will be
// regarded as an outlier
// canny_th1 50 - First threshold for
// 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()
// do_merge false - If true, incremental merging of segments
// will be perfomred
int
length_threshold
=
10
;
float
distance_threshold
=
1.41421356
f
;
double
canny_th1
=
50.0
;
double
canny_th2
=
50.0
;
int
canny_aperture_size
=
3
;
bool
do_merge
=
false
;
Ptr
<
FastLineDetector
>
fld
=
createFastLineDetector
(
length_threshold
,
distance_threshold
,
canny_th1
,
canny_th2
,
canny_aperture_size
,
do_merge
);
vector
<
Vec4f
>
lines_fld
;
// Because of some CPU's power strategy, it seems that the first running of
// an algorithm takes much longer. So here we run both of the algorithmes 10
// times to see each algorithm's processing time with sufficiently warmed-up
// CPU performance.
for
(
int
run_count
=
0
;
run_count
<
10
;
run_count
++
)
{
lines_lsd
.
clear
();
int64
start_lsd
=
getTickCount
();
lsd
->
detect
(
image
,
lines_lsd
);
// Detect the lines with LSD
double
freq
=
getTickFrequency
();
double
duration_ms_lsd
=
double
(
getTickCount
()
-
start_lsd
)
*
1000
/
freq
;
std
::
cout
<<
"Elapsed time for LSD: "
<<
duration_ms_lsd
<<
" ms."
<<
std
::
endl
;
lines_fld
.
clear
();
int64
start
=
getTickCount
();
// Detect the lines with FLD
fld
->
detect
(
image
,
lines_fld
);
double
duration_ms
=
double
(
getTickCount
()
-
start
)
*
1000
/
freq
;
std
::
cout
<<
"Ealpsed time for FLD "
<<
duration_ms
<<
" ms."
<<
std
::
endl
;
}
// Show found lines with LSD
Mat
line_image_lsd
(
image
);
lsd
->
drawSegments
(
line_image_lsd
,
lines_lsd
);
imshow
(
"LSD result"
,
line_image_lsd
);
// Show found lines with FLD
Mat
line_image_fld
(
image
);
fld
->
drawSegments
(
line_image_fld
,
lines_fld
);
imshow
(
"FLD result"
,
line_image_fld
);
waitKey
();
return
0
;
}
modules/ximgproc/src/fast_line_detector.cpp
0 → 100644
View file @
a2582d43
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include <vector>
#include <iostream>
struct
SEGMENT
{
float
x1
,
y1
,
x2
,
y2
,
angle
;
};
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
namespace
cv
{
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()
* @param _do_merge false - If true, incremental merging of segments
will be perfomred
*/
FastLineDetectorImpl
(
int
_length_threshold
=
10
,
float
_distance_threshold
=
1.414213562
f
,
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
);
/**
* 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
);
private
:
int
imagewidth
,
imageheight
,
threshold_length
;
float
threshold_dist
;
double
canny_th1
,
canny_th2
;
int
canny_aperture_size
;
bool
do_merge
;
FastLineDetectorImpl
&
operator
=
(
const
FastLineDetectorImpl
&
);
// to quiet MSVC
template
<
class
T
>
void
incidentPoint
(
const
Mat
&
l
,
T
&
pt
);
void
mergeLines
(
const
SEGMENT
&
seg1
,
const
SEGMENT
&
seg2
,
SEGMENT
&
seg_merged
);
bool
mergeSegments
(
const
SEGMENT
&
seg1
,
const
SEGMENT
&
seg2
,
SEGMENT
&
seg_merged
);
bool
getPointChain
(
const
Mat
&
img
,
Point
pt
,
Point
&
chained_pt
,
float
&
direction
,
int
step
);
double
distPointLine
(
const
Mat
&
p
,
Mat
&
l
);
void
extractSegments
(
const
std
::
vector
<
Point2i
>&
points
,
std
::
vector
<
SEGMENT
>&
segments
);
void
lineDetection
(
const
Mat
&
src
,
std
::
vector
<
SEGMENT
>&
segments_all
);
void
pointInboardTest
(
const
Mat
&
src
,
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
);
};
/////////////////////////////////////////////////////////////////////////////////////////
CV_EXPORTS
Ptr
<
FastLineDetector
>
createFastLineDetector
(
int
_length_threshold
,
float
_distance_threshold
,
double
_canny_th1
,
double
_canny_th2
,
int
_canny_aperture_size
,
bool
_do_merge
)
{
return
makePtr
<
FastLineDetectorImpl
>
(
_length_threshold
,
_distance_threshold
,
_canny_th1
,
_canny_th2
,
_canny_aperture_size
,
_do_merge
);
}
/////////////////////////////////////////////////////////////////////////////////////////
FastLineDetectorImpl
::
FastLineDetectorImpl
(
int
_length_threshold
,
float
_distance_threshold
,
double
_canny_th1
,
double
_canny_th2
,
int
_canny_aperture_size
,
bool
_do_merge
)
:
threshold_length
(
_length_threshold
),
threshold_dist
(
_distance_threshold
),
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
);
}
void
FastLineDetectorImpl
::
detect
(
InputArray
_image
,
OutputArray
_lines
)
{
CV_INSTRUMENT_REGION
();
Mat
image
=
_image
.
getMat
();
CV_Assert
(
!
image
.
empty
()
&&
image
.
type
()
==
CV_8UC1
);
std
::
vector
<
Vec4f
>
lines
;
std
::
vector
<
SEGMENT
>
segments
;
lineDetection
(
image
,
segments
);
for
(
size_t
i
=
0
;
i
<
segments
.
size
();
++
i
)
{
const
SEGMENT
seg
=
segments
[
i
];
Vec4f
line
(
seg
.
x1
,
seg
.
y1
,
seg
.
x2
,
seg
.
y2
);
lines
.
push_back
(
line
);
}
Mat
(
lines
).
copyTo
(
_lines
);
}
void
FastLineDetectorImpl
::
drawSegments
(
InputOutputArray
_image
,
InputArray
lines
,
bool
draw_arrow
)
{
CV_INSTRUMENT_REGION
();
CV_Assert
(
!
_image
.
empty
()
&&
(
_image
.
channels
()
==
1
||
_image
.
channels
()
==
3
));
Mat
gray
;
if
(
_image
.
channels
()
==
1
)
{
gray
=
_image
.
getMatRef
();
}
else
if
(
_image
.
channels
()
==
3
)
{
cvtColor
(
_image
,
gray
,
COLOR_BGR2GRAY
);
}
// 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
arrow_angle
=
30.0
;
Mat
_lines
;
_lines
=
lines
.
getMat
();
int
N
=
_lines
.
checkVector
(
4
);
// Draw segments
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
const
Vec4f
&
v
=
_lines
.
at
<
Vec4f
>
(
i
);
Point2f
b
(
v
[
0
],
v
[
1
]);
Point2f
e
(
v
[
2
],
v
[
3
]);
line
(
_image
.
getMatRef
(),
b
,
e
,
Scalar
(
0
,
0
,
255
),
1
);
if
(
draw_arrow
)
{
SEGMENT
seg
;
seg
.
x1
=
b
.
x
;
seg
.
y1
=
b
.
y
;
seg
.
x2
=
e
.
x
;
seg
.
y2
=
e
.
y
;
getAngle
(
seg
);
double
ang
=
(
double
)
seg
.
angle
;
Point2i
p1
;
p1
.
x
=
(
int
)
round
(
seg
.
x2
-
gap
*
cos
(
arrow_angle
*
CV_PI
/
180.0
+
ang
));
p1
.
y
=
(
int
)
round
(
seg
.
y2
-
gap
*
sin
(
arrow_angle
*
CV_PI
/
180.0
+
ang
));
pointInboardTest
(
_image
.
getMatRef
(),
p1
);
line
(
_image
.
getMatRef
(),
Point
((
int
)
round
(
seg
.
x2
),
(
int
)
round
(
seg
.
y2
)),
p1
,
Scalar
(
0
,
0
,
255
),
1
);
}
}
}
void
FastLineDetectorImpl
::
mergeLines
(
const
SEGMENT
&
seg1
,
const
SEGMENT
&
seg2
,
SEGMENT
&
seg_merged
)
{
double
xg
=
0.0
,
yg
=
0.0
;
double
delta1x
=
0.0
,
delta1y
=
0.0
,
delta2x
=
0.0
,
delta2y
=
0.0
;
float
ax
=
0
,
bx
=
0
,
cx
=
0
,
dx
=
0
;
float
ay
=
0
,
by
=
0
,
cy
=
0
,
dy
=
0
;
double
li
=
0.0
,
lj
=
0.0
;
double
thi
=
0.0
,
thj
=
0.0
,
thr
=
0.0
;
double
axg
=
0.0
,
bxg
=
0.0
,
cxg
=
0.0
,
dxg
=
0.0
,
delta1xg
=
0.0
,
delta2xg
=
0.0
;
ax
=
seg1
.
x1
;
ay
=
seg1
.
y1
;
bx
=
seg1
.
x2
;
by
=
seg1
.
y2
;
cx
=
seg2
.
x1
;
cy
=
seg2
.
y1
;
dx
=
seg2
.
x2
;
dy
=
seg2
.
y2
;
float
dlix
=
(
bx
-
ax
);
float
dliy
=
(
by
-
ay
);
float
dljx
=
(
dx
-
cx
);
float
dljy
=
(
dy
-
cy
);
li
=
sqrt
((
double
)
(
dlix
*
dlix
)
+
(
double
)
(
dliy
*
dliy
));
lj
=
sqrt
((
double
)
(
dljx
*
dljx
)
+
(
double
)
(
dljy
*
dljy
));
xg
=
(
li
*
(
double
)
(
ax
+
bx
)
+
lj
*
(
double
)
(
cx
+
dx
))
/
(
double
)
(
2.0
*
(
li
+
lj
));
yg
=
(
li
*
(
double
)
(
ay
+
by
)
+
lj
*
(
double
)
(
cy
+
dy
))
/
(
double
)
(
2.0
*
(
li
+
lj
));
if
(
dlix
==
0.0
f
)
thi
=
CV_PI
/
2.0
;
else
thi
=
atan
(
dliy
/
dlix
);
if
(
dljx
==
0.0
f
)
thj
=
CV_PI
/
2.0
;
else
thj
=
atan
(
dljy
/
dljx
);
if
(
fabs
(
thi
-
thj
)
<=
CV_PI
/
2.0
)
{
thr
=
(
li
*
thi
+
lj
*
thj
)
/
(
li
+
lj
);
}
else
{
double
tmp
=
thj
-
CV_PI
*
(
thj
/
fabs
(
thj
));
thr
=
li
*
thi
+
lj
*
tmp
;
thr
/=
(
li
+
lj
);
}
axg
=
((
double
)
ay
-
yg
)
*
sin
(
thr
)
+
((
double
)
ax
-
xg
)
*
cos
(
thr
);
bxg
=
((
double
)
by
-
yg
)
*
sin
(
thr
)
+
((
double
)
bx
-
xg
)
*
cos
(
thr
);
cxg
=
((
double
)
cy
-
yg
)
*
sin
(
thr
)
+
((
double
)
cx
-
xg
)
*
cos
(
thr
);
dxg
=
((
double
)
dy
-
yg
)
*
sin
(
thr
)
+
((
double
)
dx
-
xg
)
*
cos
(
thr
);
delta1xg
=
min
(
axg
,
min
(
bxg
,
min
(
cxg
,
dxg
)));
delta2xg
=
max
(
axg
,
max
(
bxg
,
max
(
cxg
,
dxg
)));
delta1x
=
delta1xg
*
cos
(
thr
)
+
xg
;
delta1y
=
delta1xg
*
sin
(
thr
)
+
yg
;
delta2x
=
delta2xg
*
cos
(
thr
)
+
xg
;
delta2y
=
delta2xg
*
sin
(
thr
)
+
yg
;
seg_merged
.
x1
=
(
float
)
delta1x
;
seg_merged
.
y1
=
(
float
)
delta1y
;
seg_merged
.
x2
=
(
float
)
delta2x
;
seg_merged
.
y2
=
(
float
)
delta2y
;
}
double
FastLineDetectorImpl
::
distPointLine
(
const
Mat
&
p
,
Mat
&
l
)
{
double
x
=
l
.
at
<
double
>
(
0
,
0
);
double
y
=
l
.
at
<
double
>
(
1
,
0
);
double
w
=
sqrt
(
x
*
x
+
y
*
y
);
l
.
at
<
double
>
(
0
,
0
)
=
x
/
w
;
l
.
at
<
double
>
(
1
,
0
)
=
y
/
w
;
l
.
at
<
double
>
(
2
,
0
)
=
l
.
at
<
double
>
(
2
,
0
)
/
w
;
return
l
.
dot
(
p
);
}
bool
FastLineDetectorImpl
::
mergeSegments
(
const
SEGMENT
&
seg1
,
const
SEGMENT
&
seg2
,
SEGMENT
&
seg_merged
)
{
double
o
[]
=
{
0.0
,
0.0
,
1.0
};
double
a
[]
=
{
0.0
,
0.0
,
1.0
};
double
b
[]
=
{
0.0
,
0.0
,
1.0
};
double
c
[
3
];
o
[
0
]
=
(
seg2
.
x1
+
seg2
.
x2
)
/
2.0
;
o
[
1
]
=
(
seg2
.
y1
+
seg2
.
y2
)
/
2.0
;
a
[
0
]
=
seg1
.
x1
;
a
[
1
]
=
seg1
.
y1
;
b
[
0
]
=
seg1
.
x2
;
b
[
1
]
=
seg1
.
y2
;
Mat
ori
=
Mat
(
3
,
1
,
CV_64FC1
,
o
).
clone
();
Mat
p1
=
Mat
(
3
,
1
,
CV_64FC1
,
a
).
clone
();
Mat
p2
=
Mat
(
3
,
1
,
CV_64FC1
,
b
).
clone
();
Mat
l1
=
Mat
(
3
,
1
,
CV_64FC1
,
c
).
clone
();
l1
=
p1
.
cross
(
p2
);
Point2f
seg1mid
,
seg2mid
;
seg1mid
.
x
=
(
seg1
.
x1
+
seg1
.
x2
)
/
2.0
f
;
seg1mid
.
y
=
(
seg1
.
y1
+
seg1
.
y2
)
/
2.0
f
;
seg2mid
.
x
=
(
seg2
.
x1
+
seg2
.
x2
)
/
2.0
f
;
seg2mid
.
y
=
(
seg2
.
y1
+
seg2
.
y2
)
/
2.0
f
;
float
seg1len
=
sqrt
((
seg1
.
x1
-
seg1
.
x2
)
*
(
seg1
.
x1
-
seg1
.
x2
)
+
(
seg1
.
y1
-
seg1
.
y2
)
*
(
seg1
.
y1
-
seg1
.
y2
));
float
seg2len
=
sqrt
((
seg2
.
x1
-
seg2
.
x2
)
*
(
seg2
.
x1
-
seg2
.
x2
)
+
(
seg2
.
y1
-
seg2
.
y2
)
*
(
seg2
.
y1
-
seg2
.
y2
));
float
middist
=
sqrt
((
seg1mid
.
x
-
seg2mid
.
x
)
*
(
seg1mid
.
x
-
seg2mid
.
x
)
+
(
seg1mid
.
y
-
seg2mid
.
y
)
*
(
seg1mid
.
y
-
seg2mid
.
y
));
float
angdiff
=
fabs
(
seg1
.
angle
-
seg2
.
angle
);
float
dist
=
(
float
)
distPointLine
(
ori
,
l1
);
if
(
fabs
(
dist
)
<=
threshold_dist
*
2.0
f
&&
middist
<=
seg1len
/
2.0
f
+
seg2len
/
2.0
f
+
20.0
f
&&
angdiff
<=
CV_PI
/
180.0
f
*
5.0
f
)
{
mergeLines
(
seg1
,
seg2
,
seg_merged
);
return
true
;
}
else
{
return
false
;
}
}
template
<
class
T
>
void
FastLineDetectorImpl
::
incidentPoint
(
const
Mat
&
l
,
T
&
pt
)
{
double
a
[]
=
{
(
double
)
pt
.
x
,
(
double
)
pt
.
y
,
1.0
};
double
b
[]
=
{
l
.
at
<
double
>
(
0
,
0
),
l
.
at
<
double
>
(
1
,
0
),
0.0
};
double
c
[
3
];
Mat
xk
=
Mat
(
3
,
1
,
CV_64FC1
,
a
).
clone
();
Mat
lh
=
Mat
(
3
,
1
,
CV_64FC1
,
b
).
clone
();
Mat
lk
=
Mat
(
3
,
1
,
CV_64FC1
,
c
).
clone
();
lk
=
xk
.
cross
(
lh
);
xk
=
lk
.
cross
(
l
);
xk
.
convertTo
(
xk
,
-
1
,
1.0
/
xk
.
at
<
double
>
(
2
,
0
));
Point2f
pt_tmp
;
pt_tmp
.
x
=
(
float
)
xk
.
at
<
double
>
(
0
,
0
)
<
0.0
f
?
0.0
f
:
(
float
)
xk
.
at
<
double
>
(
0
,
0
)
>=
(
imagewidth
-
1.0
f
)
?
(
imagewidth
-
1.0
f
)
:
(
float
)
xk
.
at
<
double
>
(
0
,
0
);
pt_tmp
.
y
=
(
float
)
xk
.
at
<
double
>
(
1
,
0
)
<
0.0
f
?
0.0
f
:
(
float
)
xk
.
at
<
double
>
(
1
,
0
)
>=
(
imageheight
-
1.0
f
)
?
(
imageheight
-
1.0
f
)
:
(
float
)
xk
.
at
<
double
>
(
1
,
0
);
pt
=
T
(
pt_tmp
);
}
void
FastLineDetectorImpl
::
extractSegments
(
const
std
::
vector
<
Point2i
>&
points
,
std
::
vector
<
SEGMENT
>&
segments
)
{
bool
is_line
;
int
i
,
j
;
SEGMENT
seg
;
Point2i
ps
,
pe
,
pt
;
std
::
vector
<
Point2i
>
l_points
;
int
total
=
(
int
)
points
.
size
();
for
(
i
=
0
;
i
+
threshold_length
<
total
;
i
++
)
{
ps
=
points
[
i
];
pe
=
points
[
i
+
threshold_length
];
double
a
[]
=
{
(
double
)
ps
.
x
,
(
double
)
ps
.
y
,
1
};
double
b
[]
=
{
(
double
)
pe
.
x
,
(
double
)
pe
.
y
,
1
};
double
c
[
3
],
d
[
3
];
Mat
p1
=
Mat
(
3
,
1
,
CV_64FC1
,
a
).
clone
();
Mat
p2
=
Mat
(
3
,
1
,
CV_64FC1
,
b
).
clone
();
Mat
p
=
Mat
(
3
,
1
,
CV_64FC1
,
c
).
clone
();
Mat
l
=
Mat
(
3
,
1
,
CV_64FC1
,
d
).
clone
();
l
=
p1
.
cross
(
p2
);
is_line
=
true
;
l_points
.
clear
();
l_points
.
push_back
(
ps
);
for
(
j
=
1
;
j
<
threshold_length
;
j
++
)
{
pt
.
x
=
points
[
i
+
j
].
x
;
pt
.
y
=
points
[
i
+
j
].
y
;
p
.
at
<
double
>
(
0
,
0
)
=
(
double
)
pt
.
x
;
p
.
at
<
double
>
(
1
,
0
)
=
(
double
)
pt
.
y
;
p
.
at
<
double
>
(
2
,
0
)
=
1.0
;
double
dist
=
distPointLine
(
p
,
l
);
if
(
fabs
(
dist
)
>
threshold_dist
)
{
is_line
=
false
;
break
;
}
l_points
.
push_back
(
pt
);
}
// Line check fail, test next point
if
(
is_line
==
false
)
continue
;
l_points
.
push_back
(
pe
);
Vec4f
line
;
fitLine
(
Mat
(
l_points
),
line
,
DIST_L2
,
0
,
0.01
,
0.01
);
a
[
0
]
=
line
[
2
];
a
[
1
]
=
line
[
3
];
b
[
0
]
=
line
[
2
]
+
line
[
0
];
b
[
1
]
=
line
[
3
]
+
line
[
1
];
p1
=
Mat
(
3
,
1
,
CV_64FC1
,
a
).
clone
();
p2
=
Mat
(
3
,
1
,
CV_64FC1
,
b
).
clone
();
l
=
p1
.
cross
(
p2
);
incidentPoint
(
l
,
ps
);
// Extending line
for
(
j
=
threshold_length
+
1
;
i
+
j
<
total
;
j
++
)
{
pt
.
x
=
points
[
i
+
j
].
x
;
pt
.
y
=
points
[
i
+
j
].
y
;
p
.
at
<
double
>
(
0
,
0
)
=
(
double
)
pt
.
x
;
p
.
at
<
double
>
(
1
,
0
)
=
(
double
)
pt
.
y
;
p
.
at
<
double
>
(
2
,
0
)
=
1.0
;
double
dist
=
distPointLine
(
p
,
l
);
if
(
fabs
(
dist
)
>
threshold_dist
)
{
fitLine
(
Mat
(
l_points
),
line
,
DIST_L2
,
0
,
0.01
,
0.01
);
a
[
0
]
=
line
[
2
];
a
[
1
]
=
line
[
3
];
b
[
0
]
=
line
[
2
]
+
line
[
0
];
b
[
1
]
=
line
[
3
]
+
line
[
1
];
p1
=
Mat
(
3
,
1
,
CV_64FC1
,
a
).
clone
();
p2
=
Mat
(
3
,
1
,
CV_64FC1
,
b
).
clone
();
l
=
p1
.
cross
(
p2
);
dist
=
distPointLine
(
p
,
l
);
if
(
fabs
(
dist
)
>
threshold_dist
)
{
j
--
;
break
;
}
}
pe
=
pt
;
l_points
.
push_back
(
pt
);
}
fitLine
(
Mat
(
l_points
),
line
,
DIST_L2
,
0
,
0.01
,
0.01
);
a
[
0
]
=
line
[
2
];
a
[
1
]
=
line
[
3
];
b
[
0
]
=
line
[
2
]
+
line
[
0
];
b
[
1
]
=
line
[
3
]
+
line
[
1
];
p1
=
Mat
(
3
,
1
,
CV_64FC1
,
a
).
clone
();
p2
=
Mat
(
3
,
1
,
CV_64FC1
,
b
).
clone
();
l
=
p1
.
cross
(
p2
);
Point2f
e1
,
e2
;
e1
.
x
=
(
float
)
ps
.
x
;
e1
.
y
=
(
float
)
ps
.
y
;
e2
.
x
=
(
float
)
pe
.
x
;
e2
.
y
=
(
float
)
pe
.
y
;
incidentPoint
(
l
,
e1
);
incidentPoint
(
l
,
e2
);
seg
.
x1
=
e1
.
x
;
seg
.
y1
=
e1
.
y
;
seg
.
x2
=
e2
.
x
;
seg
.
y2
=
e2
.
y
;
segments
.
push_back
(
seg
);
i
=
i
+
j
;
}
}
void
FastLineDetectorImpl
::
pointInboardTest
(
const
Mat
&
src
,
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
;
}
bool
FastLineDetectorImpl
::
getPointChain
(
const
Mat
&
img
,
Point
pt
,
Point
&
chained_pt
,
float
&
direction
,
int
step
)
{
int
ri
,
ci
;
int
indices
[
8
][
2
]
=
{
{
1
,
1
},
{
1
,
0
},
{
1
,
-
1
},
{
0
,
-
1
},
{
-
1
,
-
1
},{
-
1
,
0
},
{
-
1
,
1
},
{
0
,
1
}
};
float
min_dir_diff
=
7.0
f
;
Point
consistent_pt
;
int
consistent_direction
=
0
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
ci
=
pt
.
x
+
indices
[
i
][
1
];
ri
=
pt
.
y
+
indices
[
i
][
0
];
if
(
ri
<
0
||
ri
==
img
.
rows
||
ci
<
0
||
ci
==
img
.
cols
)
continue
;
if
(
img
.
at
<
unsigned
char
>
(
ri
,
ci
)
==
0
)
continue
;
if
(
step
==
0
)
{
chained_pt
.
x
=
ci
;
chained_pt
.
y
=
ri
;
// direction = (float)i;
direction
=
i
>
4
?
(
float
)(
i
-
8
)
:
(
float
)
i
;
return
true
;
}
else
{
float
curr_dir
=
i
>
4
?
(
float
)(
i
-
8
)
:
(
float
)
i
;
float
dir_diff
=
abs
(
curr_dir
-
direction
);
dir_diff
=
dir_diff
>
4.0
f
?
8.0
f
-
dir_diff
:
dir_diff
;
if
(
dir_diff
<=
min_dir_diff
)
{
min_dir_diff
=
dir_diff
;
consistent_pt
.
x
=
ci
;
consistent_pt
.
y
=
ri
;
consistent_direction
=
i
>
4
?
i
-
8
:
i
;
}
}
}
if
(
min_dir_diff
<
2.0
f
)
{
chained_pt
.
x
=
consistent_pt
.
x
;
chained_pt
.
y
=
consistent_pt
.
y
;
direction
=
(
direction
*
(
float
)
step
+
(
float
)
consistent_direction
)
/
(
float
)(
step
+
1
);
return
true
;
}
return
false
;
}
void
FastLineDetectorImpl
::
lineDetection
(
const
Mat
&
src
,
std
::
vector
<
SEGMENT
>&
segments_all
)
{
int
r
,
c
;
imageheight
=
src
.
rows
;
imagewidth
=
src
.
cols
;
std
::
vector
<
Point2i
>
points
;
std
::
vector
<
SEGMENT
>
segments
,
segments_tmp
;
Mat
canny
;
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
;
SEGMENT
seg
,
seg1
,
seg2
;
for
(
r
=
0
;
r
<
imageheight
;
r
++
)
{
for
(
c
=
0
;
c
<
imagewidth
;
c
++
)
{
// Find seeds - skip for non-seeds
if
(
canny
.
at
<
unsigned
char
>
(
r
,
c
)
==
0
)
continue
;
// Found seeds
Point2i
pt
=
Point2i
(
c
,
r
);
points
.
push_back
(
pt
);
canny
.
at
<
unsigned
char
>
(
pt
.
y
,
pt
.
x
)
=
0
;
float
direction
=
0.0
f
;
int
step
=
0
;
while
(
getPointChain
(
canny
,
pt
,
pt
,
direction
,
step
))
{
points
.
push_back
(
pt
);
step
++
;
canny
.
at
<
unsigned
char
>
(
pt
.
y
,
pt
.
x
)
=
0
;
}
if
(
points
.
size
()
<
(
unsigned
int
)
threshold_length
+
1
)
{
points
.
clear
();
continue
;
}
extractSegments
(
points
,
segments
);
if
(
segments
.
size
()
==
0
)
{
points
.
clear
();
continue
;
}
for
(
int
i
=
0
;
i
<
(
int
)
segments
.
size
();
i
++
)
{
seg
=
segments
[
i
];
float
length
=
sqrt
((
seg
.
x1
-
seg
.
x2
)
*
(
seg
.
x1
-
seg
.
x2
)
+
(
seg
.
y1
-
seg
.
y2
)
*
(
seg
.
y1
-
seg
.
y2
));
if
(
length
<
threshold_length
)
continue
;
if
(
(
seg
.
x1
<=
5.0
f
&&
seg
.
x2
<=
5.0
f
)
||
(
seg
.
y1
<=
5.0
f
&&
seg
.
y2
<=
5.0
f
)
||
(
seg
.
x1
>=
imagewidth
-
5.0
f
&&
seg
.
x2
>=
imagewidth
-
5.0
f
)
||
(
seg
.
y1
>=
imageheight
-
5.0
f
&&
seg
.
y2
>=
imageheight
-
5.0
f
)
)
continue
;
additionalOperationsOnSegment
(
src
,
seg
);
if
(
!
do_merge
)
segments_all
.
push_back
(
seg
);
segments_tmp
.
push_back
(
seg
);
}
points
.
clear
();
segments
.
clear
();
}
}
if
(
!
do_merge
)
return
;
bool
is_merged
=
false
;
int
ith
=
(
int
)
segments_tmp
.
size
()
-
1
;
int
jth
=
ith
-
1
;
while
(
ith
>
1
||
jth
>
0
)
{
seg1
=
segments_tmp
[
ith
];
seg2
=
segments_tmp
[
jth
];
SEGMENT
seg_merged
;
is_merged
=
mergeSegments
(
seg1
,
seg2
,
seg_merged
);
if
(
is_merged
==
true
)
{
seg2
=
seg_merged
;
additionalOperationsOnSegment
(
src
,
seg2
);
std
::
vector
<
SEGMENT
>::
iterator
it
=
segments_tmp
.
begin
()
+
ith
;
*
it
=
seg2
;
segments_tmp
.
erase
(
segments_tmp
.
begin
()
+
jth
);
ith
--
;
jth
=
ith
-
1
;
}
else
{
jth
--
;
}
if
(
jth
<
0
)
{
ith
--
;
jth
=
ith
-
1
;
}
}
segments_all
=
segments_tmp
;
}
inline
void
FastLineDetectorImpl
::
getAngle
(
SEGMENT
&
seg
)
{
seg
.
angle
=
(
float
)(
fastAtan2
(
seg
.
y2
-
seg
.
y1
,
seg
.
x2
-
seg
.
x1
)
/
180.0
f
*
CV_PI
);
}
void
FastLineDetectorImpl
::
additionalOperationsOnSegment
(
const
Mat
&
src
,
SEGMENT
&
seg
)
{
if
(
seg
.
x1
==
0.0
f
&&
seg
.
x2
==
0.0
f
&&
seg
.
y1
==
0.0
f
&&
seg
.
y2
==
0.0
f
)
return
;
getAngle
(
seg
);
double
ang
=
(
double
)
seg
.
angle
;
Point2f
start
=
Point2f
(
seg
.
x1
,
seg
.
y1
);
Point2f
end
=
Point2f
(
seg
.
x2
,
seg
.
y2
);
double
dx
=
0.0
,
dy
=
0.0
;
dx
=
(
double
)
end
.
x
-
(
double
)
start
.
x
;
dy
=
(
double
)
end
.
y
-
(
double
)
start
.
y
;
int
num_points
=
10
;
Point2f
*
points
=
new
Point2f
[
num_points
];
points
[
0
]
=
start
;
points
[
num_points
-
1
]
=
end
;
for
(
int
i
=
0
;
i
<
num_points
;
i
++
)
{
if
(
i
==
0
||
i
==
num_points
-
1
)
continue
;
points
[
i
].
x
=
points
[
0
].
x
+
((
float
)
dx
/
float
(
num_points
-
1
)
*
(
float
)
i
);
points
[
i
].
y
=
points
[
0
].
y
+
((
float
)
dy
/
float
(
num_points
-
1
)
*
(
float
)
i
);
}
Point2i
*
points_right
=
new
Point2i
[
num_points
];
Point2i
*
points_left
=
new
Point2i
[
num_points
];
double
gap
=
1.0
;
for
(
int
i
=
0
;
i
<
num_points
;
i
++
)
{
points_right
[
i
].
x
=
cvRound
(
points
[
i
].
x
+
gap
*
cos
(
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
].
y
=
cvRound
(
points
[
i
].
y
-
gap
*
sin
(
90.0
*
CV_PI
/
180.0
+
ang
));
pointInboardTest
(
src
,
points_right
[
i
]);
pointInboardTest
(
src
,
points_left
[
i
]);
}
int
iR
=
0
,
iL
=
0
;
for
(
int
i
=
0
;
i
<
num_points
;
i
++
)
{
iR
+=
src
.
at
<
unsigned
char
>
(
points_right
[
i
].
y
,
points_right
[
i
].
x
);
iL
+=
src
.
at
<
unsigned
char
>
(
points_left
[
i
].
y
,
points_left
[
i
].
x
);
}
if
(
iR
>
iL
)
{
std
::
swap
(
seg
.
x1
,
seg
.
x2
);
std
::
swap
(
seg
.
y1
,
seg
.
y2
);
getAngle
(
seg
);
}
delete
[]
points
;
delete
[]
points_right
;
delete
[]
points_left
;
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
=
(
int
)
round
(
seg
.
x2
-
gap
*
cos
(
arrow_angle
*
CV_PI
/
180.0
+
ang
));
p1
.
y
=
(
int
)
round
(
seg
.
y2
-
gap
*
sin
(
arrow_angle
*
CV_PI
/
180.0
+
ang
));
pointInboardTest
(
mat
,
p1
);
line
(
mat
,
Point
((
int
)
round
(
seg
.
x1
),
(
int
)
round
(
seg
.
y1
)),
Point
((
int
)
round
(
seg
.
x2
),
(
int
)
round
(
seg
.
y2
)),
bgr
,
thickness
,
1
);
if
(
directed
)
line
(
mat
,
Point
((
int
)
round
(
seg
.
x2
),
(
int
)
round
(
seg
.
y2
)),
p1
,
bgr
,
thickness
,
1
);
}
}
// namespace cv
}
// namespace ximgproc
modules/ximgproc/test/test_fld.cpp
0 → 100644
View file @
a2582d43
#include "test_precomp.hpp"
#include <vector>
using
namespace
cv
;
using
namespace
cv
::
ximgproc
;
using
namespace
std
;
const
Size
img_size
(
640
,
480
);
const
int
FLD_TEST_SEED
=
0x134679
;
const
int
EPOCHS
=
20
;
class
FLDBase
:
public
testing
::
Test
{
public
:
FLDBase
()
{
}
protected
:
Mat
test_image
;
vector
<
Vec4f
>
lines
;
RNG
rng
;
int
passedtests
;
void
GenerateWhiteNoise
(
Mat
&
image
);
void
GenerateConstColor
(
Mat
&
image
);
void
GenerateLines
(
Mat
&
image
,
const
unsigned
int
numLines
);
void
GenerateBrokenLines
(
Mat
&
image
,
const
unsigned
int
numLines
);
void
GenerateRotatedRect
(
Mat
&
image
);
virtual
void
SetUp
();
};
class
ximgproc_FLD
:
public
FLDBase
{
public
:
ximgproc_FLD
()
{
}
protected
:
};
void
FLDBase
::
GenerateWhiteNoise
(
Mat
&
image
)
{
image
=
Mat
(
img_size
,
CV_8UC1
);
rng
.
fill
(
image
,
RNG
::
UNIFORM
,
0
,
256
);
}
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
)));
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
),
2
);
}
}
void
FLDBase
::
GenerateBrokenLines
(
Mat
&
image
,
const
unsigned
int
numLines
)
{
image
=
Mat
(
img_size
,
CV_8UC1
,
Scalar
::
all
(
rng
.
uniform
(
0
,
128
)));
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
/
2
);
line
(
image
,
p1
,
p2
,
Scalar
(
255
),
2
);
p1
=
Point2i
(
y
,
img_size
.
height
/
2
+
3
);
p2
=
Point2i
(
y
,
img_size
.
height
-
10
);
line
(
image
,
p1
,
p2
,
Scalar
(
255
),
2
);
}
}
void
FLDBase
::
GenerateRotatedRect
(
Mat
&
image
)
{
image
=
Mat
::
zeros
(
img_size
,
CV_8UC1
);
Point
center
(
rng
.
uniform
(
img_size
.
width
/
4
,
img_size
.
width
*
3
/
4
),
rng
.
uniform
(
img_size
.
height
/
4
,
img_size
.
height
*
3
/
4
));
Size
rect_size
(
rng
.
uniform
(
img_size
.
width
/
8
,
img_size
.
width
/
6
),
rng
.
uniform
(
img_size
.
height
/
8
,
img_size
.
height
/
6
));
float
angle
=
rng
.
uniform
(
0.
f
,
360.
f
);
Point2f
vertices
[
4
];
RotatedRect
rRect
=
RotatedRect
(
center
,
rect_size
,
angle
);
rRect
.
points
(
vertices
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
line
(
image
,
vertices
[
i
],
vertices
[(
i
+
1
)
%
4
],
Scalar
(
255
),
3
);
}
}
void
FLDBase
::
SetUp
()
{
lines
.
clear
();
test_image
=
Mat
();
rng
=
RNG
(
FLD_TEST_SEED
);
passedtests
=
0
;
}
TEST_F
(
ximgproc_FLD
,
whiteNoise
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateWhiteNoise
(
test_image
);
Ptr
<
FastLineDetector
>
detector
=
createFastLineDetector
(
20
);
detector
->
detect
(
test_image
,
lines
);
if
(
40u
>=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
ximgproc_FLD
,
constColor
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateConstColor
(
test_image
);
Ptr
<
FastLineDetector
>
detector
=
createFastLineDetector
();
detector
->
detect
(
test_image
,
lines
);
if
(
0u
==
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
ximgproc_FLD
,
lines
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
const
unsigned
int
numOfLines
=
1
;
GenerateLines
(
test_image
,
numOfLines
);
Ptr
<
FastLineDetector
>
detector
=
createFastLineDetector
();
detector
->
detect
(
test_image
,
lines
);
if
(
numOfLines
*
2
==
lines
.
size
())
++
passedtests
;
// * 2 because of Gibbs effect
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
ximgproc_FLD
,
mergeLines
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
const
unsigned
int
numOfLines
=
1
;
GenerateBrokenLines
(
test_image
,
numOfLines
);
Ptr
<
FastLineDetector
>
detector
=
createFastLineDetector
(
10
,
1.414213562
f
,
true
);
detector
->
detect
(
test_image
,
lines
);
if
(
numOfLines
*
2
==
lines
.
size
())
++
passedtests
;
// * 2 because of Gibbs effect
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
ximgproc_FLD
,
rotatedRect
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateRotatedRect
(
test_image
);
Ptr
<
FastLineDetector
>
detector
=
createFastLineDetector
();
detector
->
detect
(
test_image
,
lines
);
if
(
2u
<=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
samples/data/corridor.jpg
0 → 100644
View file @
a2582d43
225 KB
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment