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
ef6b6964
Commit
ef6b6964
authored
Sep 20, 2016
by
Francisco Facioni
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
LSD: Avoid pre allocating a big region, std::vector allocations is quite expensive
parent
a12207c3
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
46 deletions
+46
-46
lsd.cpp
modules/imgproc/src/lsd.cpp
+46
-46
No files found.
modules/imgproc/src/lsd.cpp
View file @
ef6b6964
...
...
@@ -314,31 +314,29 @@ private:
*
* @param s Starting point for the region.
* @param reg Return: Vector of points, that are part of the region
* @param reg_size Return: The size of the region.
* @param reg_angle Return: The mean angle of the region.
* @param prec The precision by which each region angle should be aligned to the mean.
*/
void
region_grow
(
const
Point2i
&
s
,
std
::
vector
<
RegionPoint
>&
reg
,
int
&
reg_size
,
double
&
reg_angle
,
const
double
&
prec
);
double
&
reg_angle
,
const
double
&
prec
);
/**
* Finds the bounding rotated rectangle of a region.
*
* @param reg The region of points, from which the rectangle to be constructed from.
* @param reg_size The number of points in the region.
* @param reg_angle The mean angle of the region.
* @param prec The precision by which points were found.
* @param p Probability of a point with angle within 'prec'.
* @param rec Return: The generated rectangle.
*/
void
region2rect
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
int
reg_size
,
const
double
reg_angle
,
void
region2rect
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
double
reg_angle
,
const
double
prec
,
const
double
p
,
rect
&
rec
)
const
;
/**
* Compute region's angle as the principal inertia axis of the region.
* @return Regions angle.
*/
double
get_theta
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
int
&
reg_size
,
const
double
&
x
,
double
get_theta
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
double
&
x
,
const
double
&
y
,
const
double
&
reg_angle
,
const
double
&
prec
)
const
;
/**
...
...
@@ -347,14 +345,14 @@ private:
* estimated angle tolerance. If this fails to produce a rectangle with the right density of region points,
* 'reduce_region_radius' is called to try to satisfy this condition.
*/
bool
refine
(
std
::
vector
<
RegionPoint
>&
reg
,
int
&
reg_size
,
double
reg_angle
,
bool
refine
(
std
::
vector
<
RegionPoint
>&
reg
,
double
reg_angle
,
const
double
prec
,
double
p
,
rect
&
rec
,
const
double
&
density_th
);
/**
* Reduce the region size, by elimination the points far from the starting point, until that leads to
* rectangle with the right density of region points or to discard the region if too small.
*/
bool
reduce_region_radius
(
std
::
vector
<
RegionPoint
>&
reg
,
int
&
reg_size
,
double
reg_angle
,
bool
reduce_region_radius
(
std
::
vector
<
RegionPoint
>&
reg
,
double
reg_angle
,
const
double
prec
,
double
p
,
rect
&
rec
,
double
density
,
const
double
&
density_th
);
/**
...
...
@@ -460,12 +458,12 @@ void LineSegmentDetectorImpl::flsd(std::vector<Vec4f>& lines,
}
LOG_NT
=
5
*
(
log10
(
double
(
img_width
))
+
log10
(
double
(
img_height
)))
/
2
+
log10
(
11.0
);
const
int
min_reg_size
=
in
t
(
-
LOG_NT
/
log10
(
p
));
// minimal number of points in region that can give a meaningful event
const
size_t
min_reg_size
=
size_
t
(
-
LOG_NT
/
log10
(
p
));
// minimal number of points in region that can give a meaningful event
// // Initialize region only when needed
// Mat region = Mat::zeros(scaled_image.size(), CV_8UC1);
used
=
Mat_
<
uchar
>::
zeros
(
scaled_image
.
size
());
// zeros = NOTUSED
std
::
vector
<
RegionPoint
>
reg
(
img_width
*
img_height
)
;
std
::
vector
<
RegionPoint
>
reg
;
// Search for line segments
for
(
size_t
i
=
0
,
list_size
=
list
.
size
();
i
<
list_size
;
++
i
)
...
...
@@ -473,22 +471,21 @@ void LineSegmentDetectorImpl::flsd(std::vector<Vec4f>& lines,
const
Point2i
&
point
=
list
[
i
].
p
;
if
((
used
.
at
<
uchar
>
(
point
)
==
NOTUSED
)
&&
(
angles
.
at
<
double
>
(
point
)
!=
NOTDEF
))
{
int
reg_size
;
double
reg_angle
;
region_grow
(
list
[
i
].
p
,
reg
,
reg_
size
,
reg_
angle
,
prec
);
region_grow
(
list
[
i
].
p
,
reg
,
reg_angle
,
prec
);
// Ignore small regions
if
(
reg
_size
<
min_reg_size
)
{
continue
;
}
if
(
reg
.
size
()
<
min_reg_size
)
{
continue
;
}
// Construct rectangular approximation for the region
rect
rec
;
region2rect
(
reg
,
reg_
size
,
reg_
angle
,
prec
,
p
,
rec
);
region2rect
(
reg
,
reg_angle
,
prec
,
p
,
rec
);
double
log_nfa
=
-
1
;
if
(
doRefine
>
LSD_REFINE_NONE
)
{
// At least REFINE_STANDARD lvl.
if
(
!
refine
(
reg
,
reg_
size
,
reg_
angle
,
prec
,
p
,
rec
,
DENSITY_TH
))
{
continue
;
}
if
(
!
refine
(
reg
,
reg_angle
,
prec
,
p
,
rec
,
DENSITY_TH
))
{
continue
;
}
if
(
doRefine
>=
LSD_REFINE_ADV
)
{
...
...
@@ -616,23 +613,26 @@ void LineSegmentDetectorImpl::ll_angle(const double& threshold,
}
void
LineSegmentDetectorImpl
::
region_grow
(
const
Point2i
&
s
,
std
::
vector
<
RegionPoint
>&
reg
,
int
&
reg_size
,
double
&
reg_angle
,
const
double
&
prec
)
double
&
reg_angle
,
const
double
&
prec
)
{
reg
.
clear
();
// Point to this region
reg_size
=
1
;
reg
[
0
]
.
x
=
s
.
x
;
reg
[
0
]
.
y
=
s
.
y
;
reg
[
0
]
.
used
=
&
used
.
at
<
uchar
>
(
s
);
RegionPoint
seed
;
seed
.
x
=
s
.
x
;
seed
.
y
=
s
.
y
;
seed
.
used
=
&
used
.
at
<
uchar
>
(
s
);
reg_angle
=
angles
.
at
<
double
>
(
s
);
reg
[
0
].
angle
=
reg_angle
;
reg
[
0
].
modgrad
=
modgrad
.
at
<
double
>
(
s
);
seed
.
angle
=
reg_angle
;
seed
.
modgrad
=
modgrad
.
at
<
double
>
(
s
);
reg
.
push_back
(
seed
);
float
sumdx
=
float
(
std
::
cos
(
reg_angle
));
float
sumdy
=
float
(
std
::
sin
(
reg_angle
));
*
reg
[
0
]
.
used
=
USED
;
*
seed
.
used
=
USED
;
//Try neighboring regions
for
(
int
i
=
0
;
i
<
reg_size
;
++
i
)
for
(
size_t
i
=
0
;
i
<
reg
.
size
();
i
++
)
{
const
RegionPoint
&
rpoint
=
reg
[
i
];
int
xx_min
=
std
::
max
(
rpoint
.
x
-
1
,
0
),
xx_max
=
std
::
min
(
rpoint
.
x
+
1
,
img_width
-
1
);
...
...
@@ -651,13 +651,13 @@ void LineSegmentDetectorImpl::region_grow(const Point2i& s, std::vector<RegionPo
const
double
&
angle
=
angles_row
[
xx
];
// Add point
is_used
=
USED
;
RegionPoint
&
region_point
=
reg
[
reg_size
]
;
RegionPoint
region_point
;
region_point
.
x
=
xx
;
region_point
.
y
=
yy
;
region_point
.
used
=
&
is_used
;
region_point
.
modgrad
=
modgrad_row
[
xx
];
region_point
.
angle
=
angle
;
++
reg_size
;
reg
.
push_back
(
region_point
)
;
// Update region's angle
sumdx
+=
cos
(
float
(
angle
));
...
...
@@ -670,11 +670,11 @@ void LineSegmentDetectorImpl::region_grow(const Point2i& s, std::vector<RegionPo
}
}
void
LineSegmentDetectorImpl
::
region2rect
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
int
reg_size
,
void
LineSegmentDetectorImpl
::
region2rect
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
double
reg_angle
,
const
double
prec
,
const
double
p
,
rect
&
rec
)
const
{
double
x
=
0
,
y
=
0
,
sum
=
0
;
for
(
int
i
=
0
;
i
<
reg_size
;
++
i
)
for
(
size_t
i
=
0
;
i
<
reg
.
size
()
;
++
i
)
{
const
RegionPoint
&
pnt
=
reg
[
i
];
const
double
&
weight
=
pnt
.
modgrad
;
...
...
@@ -689,14 +689,14 @@ void LineSegmentDetectorImpl::region2rect(const std::vector<RegionPoint>& reg, c
x
/=
sum
;
y
/=
sum
;
double
theta
=
get_theta
(
reg
,
reg_size
,
x
,
y
,
reg_angle
,
prec
);
double
theta
=
get_theta
(
reg
,
x
,
y
,
reg_angle
,
prec
);
// Find length and width
double
dx
=
cos
(
theta
);
double
dy
=
sin
(
theta
);
double
l_min
=
0
,
l_max
=
0
,
w_min
=
0
,
w_max
=
0
;
for
(
int
i
=
0
;
i
<
reg_size
;
++
i
)
for
(
size_t
i
=
0
;
i
<
reg
.
size
()
;
++
i
)
{
double
regdx
=
double
(
reg
[
i
].
x
)
-
x
;
double
regdy
=
double
(
reg
[
i
].
y
)
-
y
;
...
...
@@ -728,7 +728,7 @@ void LineSegmentDetectorImpl::region2rect(const std::vector<RegionPoint>& reg, c
if
(
rec
.
width
<
1.0
)
rec
.
width
=
1.0
;
}
double
LineSegmentDetectorImpl
::
get_theta
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
int
&
reg_size
,
const
double
&
x
,
double
LineSegmentDetectorImpl
::
get_theta
(
const
std
::
vector
<
RegionPoint
>&
reg
,
const
double
&
x
,
const
double
&
y
,
const
double
&
reg_angle
,
const
double
&
prec
)
const
{
double
Ixx
=
0.0
;
...
...
@@ -736,7 +736,7 @@ double LineSegmentDetectorImpl::get_theta(const std::vector<RegionPoint>& reg, c
double
Ixy
=
0.0
;
// Compute inertia matrix
for
(
int
i
=
0
;
i
<
reg_size
;
++
i
)
for
(
size_t
i
=
0
;
i
<
reg
.
size
()
;
++
i
)
{
const
double
&
regx
=
reg
[
i
].
x
;
const
double
&
regy
=
reg
[
i
].
y
;
...
...
@@ -766,10 +766,10 @@ double LineSegmentDetectorImpl::get_theta(const std::vector<RegionPoint>& reg, c
return
theta
;
}
bool
LineSegmentDetectorImpl
::
refine
(
std
::
vector
<
RegionPoint
>&
reg
,
int
&
reg_size
,
double
reg_angle
,
bool
LineSegmentDetectorImpl
::
refine
(
std
::
vector
<
RegionPoint
>&
reg
,
double
reg_angle
,
const
double
prec
,
double
p
,
rect
&
rec
,
const
double
&
density_th
)
{
double
density
=
double
(
reg
_size
)
/
(
dist
(
rec
.
x1
,
rec
.
y1
,
rec
.
x2
,
rec
.
y2
)
*
rec
.
width
);
double
density
=
double
(
reg
.
size
()
)
/
(
dist
(
rec
.
x1
,
rec
.
y1
,
rec
.
x2
,
rec
.
y2
)
*
rec
.
width
);
if
(
density
>=
density_th
)
{
return
true
;
}
...
...
@@ -780,7 +780,7 @@ bool LineSegmentDetectorImpl::refine(std::vector<RegionPoint>& reg, int& reg_siz
double
sum
=
0
,
s_sum
=
0
;
int
n
=
0
;
for
(
int
i
=
0
;
i
<
reg_size
;
++
i
)
for
(
size_t
i
=
0
;
i
<
reg
.
size
()
;
++
i
)
{
*
(
reg
[
i
].
used
)
=
NOTUSED
;
if
(
dist
(
xc
,
yc
,
reg
[
i
].
x
,
reg
[
i
].
y
)
<
rec
.
width
)
...
...
@@ -797,16 +797,16 @@ bool LineSegmentDetectorImpl::refine(std::vector<RegionPoint>& reg, int& reg_siz
double
tau
=
2.0
*
sqrt
((
s_sum
-
2.0
*
mean_angle
*
sum
)
/
double
(
n
)
+
mean_angle
*
mean_angle
);
// Try new region
region_grow
(
Point
(
reg
[
0
].
x
,
reg
[
0
].
y
),
reg
,
reg_
size
,
reg_
angle
,
tau
);
region_grow
(
Point
(
reg
[
0
].
x
,
reg
[
0
].
y
),
reg
,
reg_angle
,
tau
);
if
(
reg
_size
<
2
)
{
return
false
;
}
if
(
reg
.
size
()
<
2
)
{
return
false
;
}
region2rect
(
reg
,
reg_
size
,
reg_
angle
,
prec
,
p
,
rec
);
density
=
double
(
reg
_size
)
/
(
dist
(
rec
.
x1
,
rec
.
y1
,
rec
.
x2
,
rec
.
y2
)
*
rec
.
width
);
region2rect
(
reg
,
reg_angle
,
prec
,
p
,
rec
);
density
=
double
(
reg
.
size
()
)
/
(
dist
(
rec
.
x1
,
rec
.
y1
,
rec
.
x2
,
rec
.
y2
)
*
rec
.
width
);
if
(
density
<
density_th
)
{
return
reduce_region_radius
(
reg
,
reg_
size
,
reg_
angle
,
prec
,
p
,
rec
,
density
,
density_th
);
return
reduce_region_radius
(
reg
,
reg_angle
,
prec
,
p
,
rec
,
density
,
density_th
);
}
else
{
...
...
@@ -814,7 +814,7 @@ bool LineSegmentDetectorImpl::refine(std::vector<RegionPoint>& reg, int& reg_siz
}
}
bool
LineSegmentDetectorImpl
::
reduce_region_radius
(
std
::
vector
<
RegionPoint
>&
reg
,
int
&
reg_size
,
double
reg_angle
,
bool
LineSegmentDetectorImpl
::
reduce_region_radius
(
std
::
vector
<
RegionPoint
>&
reg
,
double
reg_angle
,
const
double
prec
,
double
p
,
rect
&
rec
,
double
density
,
const
double
&
density_th
)
{
// Compute region's radius
...
...
@@ -828,25 +828,25 @@ bool LineSegmentDetectorImpl::reduce_region_radius(std::vector<RegionPoint>& reg
{
radSq
*=
0.75
*
0.75
;
// Reduce region's radius to 75% of its value
// Remove points from the region and update 'used' map
for
(
int
i
=
0
;
i
<
reg_size
;
++
i
)
for
(
size_t
i
=
0
;
i
<
reg
.
size
()
;
++
i
)
{
if
(
distSq
(
xc
,
yc
,
double
(
reg
[
i
].
x
),
double
(
reg
[
i
].
y
))
>
radSq
)
{
// Remove point from the region
*
(
reg
[
i
].
used
)
=
NOTUSED
;
std
::
swap
(
reg
[
i
],
reg
[
reg
_size
-
1
]);
--
reg_size
;
std
::
swap
(
reg
[
i
],
reg
[
reg
.
size
()
-
1
]);
reg
.
pop_back
()
;
--
i
;
// To avoid skipping one point
}
}
if
(
reg
_size
<
2
)
{
return
false
;
}
if
(
reg
.
size
()
<
2
)
{
return
false
;
}
// Re-compute rectangle
region2rect
(
reg
,
reg_size
,
reg_angle
,
prec
,
p
,
rec
);
region2rect
(
reg
,
reg_angle
,
prec
,
p
,
rec
);
// Re-compute region points density
density
=
double
(
reg
_size
)
/
density
=
double
(
reg
.
size
()
)
/
(
dist
(
rec
.
x1
,
rec
.
y1
,
rec
.
x2
,
rec
.
y2
)
*
rec
.
width
);
}
...
...
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