Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dlib
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
钟尚武
dlib
Commits
c56eaf0a
Commit
c56eaf0a
authored
Apr 25, 2018
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added normalize_image_gradients() and remove_incoherent_edge_pixels().
parent
3c052e8e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
163 additions
and
0 deletions
+163
-0
edge_detector.h
dlib/image_transforms/edge_detector.h
+101
-0
edge_detector_abstract.h
dlib/image_transforms/edge_detector_abstract.h
+62
-0
No files found.
dlib/image_transforms/edge_detector.h
View file @
c56eaf0a
...
...
@@ -6,6 +6,8 @@
#include "edge_detector_abstract.h"
#include "../pixel.h"
#include "../array2d.h"
#include "../geometry.h"
#include <vector>
namespace
dlib
{
...
...
@@ -292,6 +294,105 @@ namespace dlib
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
image_type
>
void
normalize_image_gradients
(
image_type
&
img1_
,
image_type
&
img2_
)
{
image_view
<
image_type
>
img1
(
img1_
);
image_view
<
image_type
>
img2
(
img2_
);
using
pixel_type
=
typename
image_traits
<
image_type
>::
pixel_type
;
static_assert
(
std
::
is_same
<
pixel_type
,
float
>::
value
||
std
::
is_same
<
pixel_type
,
double
>::
value
||
std
::
is_same
<
pixel_type
,
long
double
>::
value
,
"normalize_image_gradients() requires the input images to use floating point pixel types."
);
DLIB_CASSERT
(
img1
.
nr
()
==
img2
.
nr
());
DLIB_CASSERT
(
img1
.
nc
()
==
img2
.
nc
());
// normalize all the gradients
for
(
long
r
=
0
;
r
<
img1
.
nr
();
++
r
)
{
for
(
long
c
=
0
;
c
<
img1
.
nc
();
++
c
)
{
if
(
img1
[
r
][
c
]
!=
0
||
img2
[
r
][
c
]
!=
0
)
{
double
len
=
std
::
sqrt
(
img1
[
r
][
c
]
*
img1
[
r
][
c
]
+
img2
[
r
][
c
]
*
img2
[
r
][
c
]);
img1
[
r
][
c
]
/=
len
;
img2
[
r
][
c
]
/=
len
;
}
}
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
image_type
>
std
::
vector
<
point
>
remove_incoherent_edge_pixels
(
const
std
::
vector
<
point
>&
line
,
const
image_type
&
horz_gradient_
,
const
image_type
&
vert_gradient_
,
double
angle_threshold
)
{
const_image_view
<
image_type
>
horz_gradient
(
horz_gradient_
);
const_image_view
<
image_type
>
vert_gradient
(
vert_gradient_
);
DLIB_CASSERT
(
horz_gradient
.
nr
()
==
vert_gradient
.
nr
());
DLIB_CASSERT
(
horz_gradient
.
nc
()
==
vert_gradient
.
nc
());
DLIB_CASSERT
(
angle_threshold
>=
0
);
#ifdef ENABLE_ASSERTS
for
(
auto
&
p
:
line
)
DLIB_ASSERT
(
get_rect
(
horz_gradient
).
contains
(
p
),
"All line points must be inside the given images."
);
#endif
// We make sure that each vector is within this threshold of the mean vector. So
// to make sure they are pairwise within the user supplied angel threshold we need
// to divide by 2 before we proceed.
angle_threshold
/=
2
;
const
double
dotthresh
=
std
::
cos
(
angle_threshold
*
pi
/
180
);
// find the average gradient on this line
dpoint
avg
;
for
(
auto
p
:
line
)
avg
+=
dpoint
(
horz_gradient
[
p
.
y
()][
p
.
x
()],
vert_gradient
[
p
.
y
()][
p
.
x
()]);
dpoint
ref
=
avg
.
normalize
();
// now iterate a few times and find the most common average gradient.
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
avg
=
dpoint
();
for
(
auto
p
:
line
)
{
const
dpoint
v
(
horz_gradient
[
p
.
y
()][
p
.
x
()],
vert_gradient
[
p
.
y
()][
p
.
x
()]);
const
double
dp
=
ref
.
dot
(
v
);
if
(
dp
>
dotthresh
)
avg
+=
v
;
else
if
(
-
dp
>
dotthresh
)
avg
-=
v
;
}
ref
=
avg
.
normalize
();
}
// now remove all the points that deviate from the average gradient too much.
std
::
vector
<
point
>
newpixels
;
for
(
auto
p
:
line
)
{
dpoint
v
(
horz_gradient
[
p
.
y
()][
p
.
x
()],
vert_gradient
[
p
.
y
()][
p
.
x
()]);
if
(
std
::
abs
(
ref
.
dot
(
v
))
>
dotthresh
)
newpixels
.
push_back
(
p
);
}
return
newpixels
;
}
// ----------------------------------------------------------------------------------------
}
...
...
dlib/image_transforms/edge_detector_abstract.h
View file @
c56eaf0a
...
...
@@ -5,6 +5,8 @@
#include "../pixel.h"
#include "../image_processing/generic_image.h"
#include "../geometry.h"
#include <vector>
namespace
dlib
{
...
...
@@ -103,6 +105,66 @@ namespace dlib
- performs assign_pixel(#out_img[r][c], 0)
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
image_type
>
void
normalize_image_gradients
(
image_type
&
img1
,
image_type
&
img2
);
/*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- image_type contains float, double, or long double pixels.
- img1.nr() == img2.nr()
- img1.nc() == img2.nc()
ensures
- #out_img.nr() = img1.nr()
- #out_img.nc() = img1.nc()
- This function assumes img1 and img2 are the two gradient images produced by a
function like sobel_edge_detector(). It then unit normalizes the gradient
vectors. That is, for all valid r and c, this function ensures that:
- #img1[r][c]*img1[r][c] + #img2[r][c]*img2[r][c] == 1
unless both img1[r][c] and img2[r][c] were 0 initially, then they stay zero.
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
image_type
>
std
::
vector
<
point
>
remove_incoherent_edge_pixels
(
const
std
::
vector
<
point
>&
line
,
const
image_type
&
horz_gradient
,
const
image_type
&
vert_gradient
,
const
double
angle_threshold
);
/*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
- image_type contains float, double, or long double pixels.
- horz_gradient.nr() == vert_gradient.nr()
- horz_gradient.nc() == vert_gradient.nc()
- horz_gradient and vert_gradient represent unit normalized vectors. That is,
you should have called normalize_image_gradients(horz_gradient,vert_gradient)
or otherwise caused all the gradients to have unit norm.
- for all valid i:
get_rect(horz_gradient).contains(line[i])
ensures
- This routine looks at all the points in the given line and discards the ones that
have outlying gradient directions. To be specific, this routine returns a set
of points PTS such that:
- for all valid i,j:
- The difference in angle between the gradients for PTS[i] and PTS[j] is
less than angle_threshold degrees.
- PTS.size() <= line.size()
- PTS is just line with some elements removed.
!*/
// ----------------------------------------------------------------------------------------
}
...
...
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