Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
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
Commits
45f7c83d
Commit
45f7c83d
authored
Jul 24, 2013
by
Roman Donchenko
Committed by
OpenCV Buildbot
Jul 24, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1119 from 23pointsNorth:lsd
parents
b2d359b6
ae93a3e6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
380 additions
and
0 deletions
+380
-0
imgproc.hpp
modules/imgproc/include/opencv2/imgproc.hpp
+61
-0
lsd.cpp
modules/imgproc/src/lsd.cpp
+0
-0
test_lsd.cpp
modules/imgproc/test/test_lsd.cpp
+265
-0
lsd_lines.cpp
samples/cpp/lsd_lines.cpp
+54
-0
No files found.
modules/imgproc/include/opencv2/imgproc.hpp
View file @
45f7c83d
...
...
@@ -191,6 +191,12 @@ enum { HOUGH_STANDARD = 0,
HOUGH_GRADIENT
=
3
};
//! Variants of Line Segment Detector
enum
{
LSD_REFINE_NONE
=
0
,
LSD_REFINE_STD
=
1
,
LSD_REFINE_ADV
=
2
};
//! Histogram comparison methods
enum
{
HISTCMP_CORREL
=
0
,
HISTCMP_CHISQR
=
1
,
...
...
@@ -829,7 +835,62 @@ protected:
Point2f
bottomRight
;
};
class
LineSegmentDetector
:
public
Algorithm
{
public
:
/**
* Detect lines in the input image with the specified ROI.
*
* @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 Vec4i elements specifying the beginning and ending point of a line.
* Where Vec4i is (x1, y1, x2, y2), point 1 is the start, point 2 - end.
* Returned lines are strictly oriented depending on the gradient.
* @param _roi Return: ROI of the image, where lines are to be found. If specified, the returning
* lines coordinates are image wise.
* @param width Return: Vector of widths of the regions, where the lines are found. E.g. Width of line.
* @param prec Return: Vector of precisions with which the lines are found.
* @param nfa Return: Vector containing number of false alarms in the line region, with precision of 10%.
* The bigger the value, logarithmically better the detection.
* * -1 corresponds to 10 mean false alarms
* * 0 corresponds to 1 mean false alarm
* * 1 corresponds to 0.1 mean false alarms
* This vector will be calculated _only_ when the objects type is REFINE_ADV
*/
virtual
void
detect
(
const
InputArray
_image
,
OutputArray
_lines
,
OutputArray
width
=
noArray
(),
OutputArray
prec
=
noArray
(),
OutputArray
nfa
=
noArray
())
=
0
;
/**
* 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
*/
virtual
void
drawSegments
(
InputOutputArray
image
,
const
InputArray
lines
)
=
0
;
/**
* Draw both vectors on the image canvas. Uses blue for lines 1 and red for lines 2.
*
* @param image The image, where lines will be drawn.
* Should have the size of the image, where the lines were found
* @param lines1 The first lines that need to be drawn. Color - Blue.
* @param lines2 The second lines that need to be drawn. Color - Red.
* @return The number of mismatching pixels between lines1 and lines2.
*/
virtual
int
compareSegments
(
const
Size
&
size
,
const
InputArray
lines1
,
const
InputArray
lines2
,
Mat
*
image
=
0
)
=
0
;
virtual
~
LineSegmentDetector
()
{};
};
//! Returns a pointer to a LineSegmentDetector class.
CV_EXPORTS
Ptr
<
LineSegmentDetector
>
createLineSegmentDetectorPtr
(
int
_refine
=
LSD_REFINE_STD
,
double
_scale
=
0.8
,
double
_sigma_scale
=
0.6
,
double
_quant
=
2.0
,
double
_ang_th
=
22.5
,
double
_log_eps
=
0
,
double
_density_th
=
0.7
,
int
_n_bins
=
1024
);
//! returns type (one of KERNEL_*) of 1D or 2D kernel specified by its coefficients.
CV_EXPORTS
int
getKernelType
(
InputArray
kernel
,
Point
anchor
);
...
...
modules/imgproc/src/lsd.cpp
0 → 100644
View file @
45f7c83d
This diff is collapsed.
Click to expand it.
modules/imgproc/test/test_lsd.cpp
0 → 100644
View file @
45f7c83d
#include "test_precomp.hpp"
#include <vector>
using
namespace
cv
;
using
namespace
std
;
const
Size
img_size
(
640
,
480
);
const
int
LSD_TEST_SEED
=
0x134679
;
const
int
EPOCHS
=
20
;
class
LSDBase
:
public
testing
::
Test
{
public
:
LSDBase
()
{};
protected
:
Mat
test_image
;
vector
<
Vec4i
>
lines
;
RNG
rng
;
int
passedtests
;
void
GenerateWhiteNoise
(
Mat
&
image
);
void
GenerateConstColor
(
Mat
&
image
);
void
GenerateLines
(
Mat
&
image
,
const
unsigned
int
numLines
);
void
GenerateRotatedRect
(
Mat
&
image
);
virtual
void
SetUp
();
};
class
Imgproc_LSD_ADV
:
public
LSDBase
{
public
:
Imgproc_LSD_ADV
()
{};
protected
:
};
class
Imgproc_LSD_STD
:
public
LSDBase
{
public
:
Imgproc_LSD_STD
()
{};
protected
:
};
class
Imgproc_LSD_NONE
:
public
LSDBase
{
public
:
Imgproc_LSD_NONE
()
{};
protected
:
};
void
LSDBase
::
GenerateWhiteNoise
(
Mat
&
image
)
{
image
=
Mat
(
img_size
,
CV_8UC1
);
rng
.
fill
(
image
,
RNG
::
UNIFORM
,
0
,
256
);
}
void
LSDBase
::
GenerateConstColor
(
Mat
&
image
)
{
image
=
Mat
(
img_size
,
CV_8UC1
,
Scalar
::
all
(
rng
.
uniform
(
0
,
256
)));
}
void
LSDBase
::
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
),
3
);
}
}
void
LSDBase
::
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
LSDBase
::
SetUp
()
{
lines
.
clear
();
test_image
=
Mat
();
rng
=
RNG
(
LSD_TEST_SEED
);
passedtests
=
0
;
}
TEST_F
(
Imgproc_LSD_ADV
,
whiteNoise
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateWhiteNoise
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_ADV
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
40
)
>=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_ADV
,
constColor
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateConstColor
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_ADV
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
0
)
==
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_ADV
,
lines
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
const
unsigned
int
numOfLines
=
1
;
GenerateLines
(
test_image
,
numOfLines
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_ADV
);
detector
->
detect
(
test_image
,
lines
);
if
(
numOfLines
*
2
==
lines
.
size
())
++
passedtests
;
// * 2 because of Gibbs effect
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_ADV
,
rotatedRect
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateRotatedRect
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_ADV
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
2
)
<=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_STD
,
whiteNoise
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateWhiteNoise
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_STD
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
50
)
>=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_STD
,
constColor
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateConstColor
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_STD
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
0
)
==
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_STD
,
lines
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
const
unsigned
int
numOfLines
=
1
;
GenerateLines
(
test_image
,
numOfLines
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_STD
);
detector
->
detect
(
test_image
,
lines
);
if
(
numOfLines
*
2
==
lines
.
size
())
++
passedtests
;
// * 2 because of Gibbs effect
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_STD
,
rotatedRect
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateRotatedRect
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_STD
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
4
)
<=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_NONE
,
whiteNoise
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateWhiteNoise
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_STD
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
50
)
>=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_NONE
,
constColor
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateConstColor
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_NONE
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
0
)
==
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_NONE
,
lines
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
const
unsigned
int
numOfLines
=
1
;
GenerateLines
(
test_image
,
numOfLines
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_NONE
);
detector
->
detect
(
test_image
,
lines
);
if
(
numOfLines
*
2
==
lines
.
size
())
++
passedtests
;
// * 2 because of Gibbs effect
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
TEST_F
(
Imgproc_LSD_NONE
,
rotatedRect
)
{
for
(
int
i
=
0
;
i
<
EPOCHS
;
++
i
)
{
GenerateRotatedRect
(
test_image
);
Ptr
<
LineSegmentDetector
>
detector
=
createLineSegmentDetectorPtr
(
LSD_REFINE_NONE
);
detector
->
detect
(
test_image
,
lines
);
if
(
uint
(
8
)
<=
lines
.
size
())
++
passedtests
;
}
ASSERT_EQ
(
EPOCHS
,
passedtests
);
}
samples/cpp/lsd_lines.cpp
0 → 100644
View file @
45f7c83d
#include <iostream>
#include <string>
#include "opencv2/core/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using
namespace
std
;
using
namespace
cv
;
int
main
(
int
argc
,
char
**
argv
)
{
std
::
string
in
;
if
(
argc
!=
2
)
{
std
::
cout
<<
"Usage: lsd_lines [input image]. Now loading building.jpg"
<<
std
::
endl
;
in
=
"building.jpg"
;
}
else
{
in
=
argv
[
1
];
}
Mat
image
=
imread
(
in
,
IMREAD_GRAYSCALE
);
#if 0
Canny(image, image, 50, 200, 3); // Apply canny edge
#endif
// Create and LSD detector with standard or no refinement.
#if 1
Ptr
<
LineSegmentDetector
>
ls
=
createLineSegmentDetectorPtr
(
LSD_REFINE_STD
);
#else
Ptr
<
LineSegmentDetector
>
ls
=
createLineSegmentDetectorPtr
(
LSD_REFINE_NONE
);
#endif
double
start
=
double
(
getTickCount
());
vector
<
Vec4i
>
lines_std
;
// Detect the lines
ls
->
detect
(
image
,
lines_std
);
double
duration_ms
=
(
double
(
getTickCount
())
-
start
)
*
1000
/
getTickFrequency
();
std
::
cout
<<
"It took "
<<
duration_ms
<<
" ms."
<<
std
::
endl
;
// Show found lines
Mat
drawnLines
(
image
);
ls
->
drawSegments
(
drawnLines
,
lines_std
);
imshow
(
"Standard refinement"
,
drawnLines
);
waitKey
();
return
0
;
}
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