Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
81d57e72
Commit
81d57e72
authored
May 27, 2018
by
Davis King
Browse files
Cleaned up min_barrier_distance() code a bit and also made it more robust.
parent
0249bcb9
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
145 additions
and
135 deletions
+145
-135
dlib/image_transforms/segment_image.h
dlib/image_transforms/segment_image.h
+145
-135
No files found.
dlib/image_transforms/segment_image.h
View file @
81d57e72
...
...
@@ -728,127 +728,26 @@ namespace dlib
namespace
impl
{
template
<
typename
T
>
void
mbd_raster_scan
(
const
T
&
img
,
array2d
<
rgb_pixel
>&
dist
,
array2d
<
rgb_pixel
>&
lower
,
array2d
<
rgb_pixel
>&
upper
,
bool
do_left_right_scans
)
{
auto
area
=
shrink_rect
(
get_rect
(
img
),
1
);
auto
check_neighbor
=
[
&
](
long
r
,
long
c
,
long
neighbor_r
,
long
neighbor_c
)
{
auto
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
red
,
img
[
r
][
c
].
red
);
auto
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
red
,
img
[
r
][
c
].
red
);
auto
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
].
red
)
{
lower
[
r
][
c
].
red
=
l
;
upper
[
r
][
c
].
red
=
u
;
dist
[
r
][
c
].
red
=
d
;
}
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
green
,
img
[
r
][
c
].
green
);
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
green
,
img
[
r
][
c
].
green
);
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
].
green
)
{
lower
[
r
][
c
].
green
=
l
;
upper
[
r
][
c
].
green
=
u
;
dist
[
r
][
c
].
green
=
d
;
}
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
blue
,
img
[
r
][
c
].
blue
);
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
blue
,
img
[
r
][
c
].
blue
);
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
].
blue
)
{
lower
[
r
][
c
].
blue
=
l
;
upper
[
r
][
c
].
blue
=
u
;
dist
[
r
][
c
].
blue
=
d
;
}
};
// scan top to bottom
for
(
long
r
=
area
.
top
();
r
<=
area
.
bottom
();
++
r
)
{
for
(
long
c
=
area
.
left
();
c
<=
area
.
right
();
++
c
)
{
check_neighbor
(
r
,
c
,
r
-
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
-
1
);
}
}
// scan bottom to top
for
(
long
r
=
area
.
bottom
();
r
>=
area
.
top
();
--
r
)
{
for
(
long
c
=
area
.
right
();
c
>=
area
.
left
();
--
c
)
{
check_neighbor
(
r
,
c
,
r
+
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
+
1
);
}
}
if
(
do_left_right_scans
)
{
// scan left to right
for
(
long
c
=
area
.
left
();
c
<=
area
.
right
();
++
c
)
{
for
(
long
r
=
area
.
top
();
r
<=
area
.
bottom
();
++
r
)
{
check_neighbor
(
r
,
c
,
r
-
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
-
1
);
}
}
// scan right to left
for
(
long
c
=
area
.
right
();
c
>=
area
.
left
();
--
c
)
{
for
(
long
r
=
area
.
bottom
();
r
>=
area
.
top
();
--
r
)
{
check_neighbor
(
r
,
c
,
r
+
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
+
1
);
}
}
}
}
// ------------------------------------------------------------------------------------
template
<
typename
T
,
typename
U
,
typename
pixel_type
>
void
mbd_raster_scan
(
const
T
&
img
,
U
&
dist
,
array2d
<
pixel_type
>&
lower
,
array2d
<
pixel_type
>&
upper
,
bool
do_left_right_scans
template
<
typename
funct1_t
,
typename
funct2_t
>
inline
void
mbd_raster_scan_top_bottom
(
const
rectangle
&
area
,
funct1_t
funct1
,
funct2_t
funct2
)
{
auto
area
=
shrink_rect
(
get_rect
(
img
),
1
);
auto
check_neighbor
=
[
&
](
long
r
,
long
c
,
long
neighbor_r
,
long
neighbor_c
)
{
auto
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
],
get_pixel_intensity
(
img
[
r
][
c
]));
auto
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
],
get_pixel_intensity
(
img
[
r
][
c
]));
auto
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
])
{
lower
[
r
][
c
]
=
l
;
upper
[
r
][
c
]
=
u
;
dist
[
r
][
c
]
=
d
;
}
};
// scan top to bottom
for
(
long
r
=
area
.
top
();
r
<=
area
.
bottom
();
++
r
)
{
for
(
long
c
=
area
.
left
();
c
<=
area
.
right
();
++
c
)
{
check_neighbor
(
r
,
c
,
r
-
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
-
1
);
funct1
(
r
,
c
,
r
-
1
,
c
);
funct2
(
r
,
c
,
r
,
c
-
1
);
}
}
...
...
@@ -857,20 +756,27 @@ namespace dlib
{
for
(
long
c
=
area
.
right
();
c
>=
area
.
left
();
--
c
)
{
check_neighbor
(
r
,
c
,
r
+
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
+
1
);
funct2
(
r
,
c
,
r
+
1
,
c
);
funct2
(
r
,
c
,
r
,
c
+
1
);
}
}
}
if
(
do_left_right_scans
)
template
<
typename
funct_t
>
inline
void
mbd_raster_scan_left_right
(
const
rectangle
&
area
,
funct_t
funct
)
{
// scan left to right
for
(
long
c
=
area
.
left
();
c
<=
area
.
right
();
++
c
)
{
for
(
long
r
=
area
.
top
();
r
<=
area
.
bottom
();
++
r
)
{
check_neighbor
(
r
,
c
,
r
-
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
-
1
);
funct
(
r
,
c
,
r
-
1
,
c
);
funct
(
r
,
c
,
r
,
c
-
1
);
}
}
...
...
@@ -879,9 +785,8 @@ namespace dlib
{
for
(
long
r
=
area
.
bottom
();
r
>=
area
.
top
();
--
r
)
{
check_neighbor
(
r
,
c
,
r
+
1
,
c
);
check_neighbor
(
r
,
c
,
r
,
c
+
1
);
}
funct
(
r
,
c
,
r
+
1
,
c
);
funct
(
r
,
c
,
r
,
c
+
1
);
}
}
}
...
...
@@ -919,9 +824,45 @@ namespace dlib
assign_image
(
lower
,
img
);
assign_image
(
upper
,
img
);
for
(
size_t
i
=
0
;
i
<
iterations
;
++
i
)
impl
::
mbd_raster_scan
(
img
,
dist
,
lower
,
upper
,
do_left_right_scans
);
auto
check_neighbor
=
[
&
](
long
r
,
long
c
,
long
neighbor_r
,
long
neighbor_c
)
{
auto
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
],
get_pixel_intensity
(
img
[
r
][
c
]));
auto
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
],
get_pixel_intensity
(
img
[
r
][
c
]));
auto
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
])
{
lower
[
r
][
c
]
=
l
;
upper
[
r
][
c
]
=
u
;
dist
[
r
][
c
]
=
d
;
}
};
// The very first pass we make needs to use this version. We do this because the
// initial setting of dist is the max pixel value, but that value might naturally
// occur in the data, especially for 8bit images. So we use this version on the
// first pass to make sure that the lower and upper bounds get set with real data.
auto
check_neighbor_init
=
[
&
](
long
r
,
long
c
,
long
neighbor_r
,
long
neighbor_c
)
{
auto
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
],
get_pixel_intensity
(
img
[
r
][
c
]));
auto
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
],
get_pixel_intensity
(
img
[
r
][
c
]));
auto
d
=
u
-
l
;
lower
[
r
][
c
]
=
l
;
upper
[
r
][
c
]
=
u
;
dist
[
r
][
c
]
=
d
;
};
auto
area
=
shrink_rect
(
get_rect
(
img
),
1
);
impl
::
mbd_raster_scan_top_bottom
(
area
,
check_neighbor_init
,
check_neighbor
);
if
(
do_left_right_scans
)
impl
::
mbd_raster_scan_left_right
(
area
,
check_neighbor
);
for
(
size_t
i
=
1
;
i
<
iterations
;
++
i
)
{
impl
::
mbd_raster_scan_top_bottom
(
area
,
check_neighbor
,
check_neighbor
);
if
(
do_left_right_scans
)
impl
::
mbd_raster_scan_left_right
(
area
,
check_neighbor
);
}
}
// ----------------------------------------------------------------------------------------
...
...
@@ -943,23 +884,92 @@ namespace dlib
"min_barrier_distance() requires a grayscale output image."
);
const_image_view
<
in_image_type
>
img
(
img_
);
image_view
<
out_image_type
>
dist
(
dist_
);
typedef
typename
image_traits
<
in_image_type
>::
pixel_type
pixel_type
;
array2d
<
rgb_pixel
>
temp_
dist
(
img
.
nr
(),
img
.
nc
());
array2d
<
rgb_pixel
>
dist
(
img
.
nr
(),
img
.
nc
());
array2d
<
rgb_pixel
>
lower
,
upper
;
assign_all_pixels
(
temp_
dist
,
pixel_traits
<
pixel_type
>::
max
());
zero_border_pixels
(
temp_
dist
,
1
,
1
);
assign_all_pixels
(
dist
,
pixel_traits
<
pixel_type
>::
max
());
zero_border_pixels
(
dist
,
1
,
1
);
assign_image
(
lower
,
img
);
assign_image
(
upper
,
img
);
for
(
size_t
i
=
0
;
i
<
iterations
;
++
i
)
impl
::
mbd_raster_scan
(
img
,
temp_dist
,
lower
,
upper
,
do_left_right_scans
);
auto
check_neighbor
=
[
&
](
long
r
,
long
c
,
long
neighbor_r
,
long
neighbor_c
)
{
auto
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
red
,
img
[
r
][
c
].
red
);
auto
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
red
,
img
[
r
][
c
].
red
);
auto
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
].
red
)
{
lower
[
r
][
c
].
red
=
l
;
upper
[
r
][
c
].
red
=
u
;
dist
[
r
][
c
].
red
=
d
;
}
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
green
,
img
[
r
][
c
].
green
);
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
green
,
img
[
r
][
c
].
green
);
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
].
green
)
{
lower
[
r
][
c
].
green
=
l
;
upper
[
r
][
c
].
green
=
u
;
dist
[
r
][
c
].
green
=
d
;
}
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
blue
,
img
[
r
][
c
].
blue
);
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
blue
,
img
[
r
][
c
].
blue
);
d
=
u
-
l
;
if
(
d
<
dist
[
r
][
c
].
blue
)
{
lower
[
r
][
c
].
blue
=
l
;
upper
[
r
][
c
].
blue
=
u
;
dist
[
r
][
c
].
blue
=
d
;
}
};
// The very first pass we make needs to use this version. We do this because the
// initial setting of dist is the max pixel value, but that value might naturally
// occur in the data, especially for 8bit images. So we use this version on the
// first pass to make sure that the lower and upper bounds get set with real data.
auto
check_neighbor_init
=
[
&
](
long
r
,
long
c
,
long
neighbor_r
,
long
neighbor_c
)
{
auto
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
red
,
img
[
r
][
c
].
red
);
auto
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
red
,
img
[
r
][
c
].
red
);
auto
d
=
u
-
l
;
lower
[
r
][
c
].
red
=
l
;
upper
[
r
][
c
].
red
=
u
;
dist
[
r
][
c
].
red
=
d
;
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
green
,
img
[
r
][
c
].
green
);
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
green
,
img
[
r
][
c
].
green
);
d
=
u
-
l
;
lower
[
r
][
c
].
green
=
l
;
upper
[
r
][
c
].
green
=
u
;
dist
[
r
][
c
].
green
=
d
;
l
=
std
::
min
(
lower
[
neighbor_r
][
neighbor_c
].
blue
,
img
[
r
][
c
].
blue
);
u
=
std
::
max
(
upper
[
neighbor_r
][
neighbor_c
].
blue
,
img
[
r
][
c
].
blue
);
d
=
u
-
l
;
lower
[
r
][
c
].
blue
=
l
;
upper
[
r
][
c
].
blue
=
u
;
dist
[
r
][
c
].
blue
=
d
;
};
auto
area
=
shrink_rect
(
get_rect
(
img
),
1
);
impl
::
mbd_raster_scan_top_bottom
(
area
,
check_neighbor_init
,
check_neighbor
);
if
(
do_left_right_scans
)
impl
::
mbd_raster_scan_left_right
(
area
,
check_neighbor
);
for
(
size_t
i
=
1
;
i
<
iterations
;
++
i
)
{
impl
::
mbd_raster_scan_top_bottom
(
area
,
check_neighbor
,
check_neighbor
);
if
(
do_left_right_scans
)
impl
::
mbd_raster_scan_left_right
(
area
,
check_neighbor
);
}
// convert to grayscale for output.
assign_image
(
dist
,
temp
_dist
);
assign_image
(
dist_
,
dist
);
}
// ----------------------------------------------------------------------------------------
...
...
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