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
9e54a208
Commit
9e54a208
authored
Sep 04, 2017
by
Davis King
Browse files
Refactored create_tiled_pyramid() code to remove unnecessary copying. It's now
about 2x faster. The code is cleaner too.
parent
8c2d87db
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
72 deletions
+107
-72
dlib/image_transforms/image_pyramid.h
dlib/image_transforms/image_pyramid.h
+107
-72
No files found.
dlib/image_transforms/image_pyramid.h
View file @
9e54a208
...
@@ -1023,99 +1023,134 @@ namespace dlib
...
@@ -1023,99 +1023,134 @@ namespace dlib
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
namespace
impl
typename
pyramid_type
,
{
typename
image_type1
,
template
<
typename
pyramid_type
>
typename
image_type2
void
compute_tiled_image_pyramid_details
(
>
const
pyramid_type
&
pyr
,
void
create_tiled_pyramid
(
long
nr
,
const
image_type1
&
img
,
long
nc
,
image_type2
&
out_img
,
const
unsigned
long
padding
,
const
unsigned
long
outer_padding
,
std
::
vector
<
rectangle
>&
rects
,
std
::
vector
<
rectangle
>&
rects
,
const
unsigned
long
p
adding
=
10
,
long
&
p
yramid_image_nr
,
const
unsigned
long
outer_padding
=
0
long
&
pyramid_image_nc
)
)
{
{
DLIB_ASSERT
(
!
is_same_object
(
img
,
out_img
));
rects
.
clear
();
rects
.
clear
();
if
(
n
um_rows
(
img
)
*
num_columns
(
img
)
==
0
)
if
(
n
r
*
nc
==
0
)
{
{
set_image_size
(
out_img
,
0
,
0
);
pyramid_image_nr
=
0
;
pyramid_image_nc
=
0
;
return
;
return
;
}
}
const
long
min_height
=
5
;
const
long
min_height
=
5
;
pyramid_type
pyr
;
rects
.
reserve
(
100
);
std
::
vector
<
matrix
<
rgb_pixel
>>
pyramid
;
rects
.
push_back
(
rectangle
(
nc
,
nr
));
matrix
<
rgb_pixel
>
temp
;
assign_image
(
temp
,
img
);
pyramid
.
push_back
(
std
::
move
(
temp
));
// build the whole pyramid
// build the whole pyramid
while
(
true
)
while
(
true
)
{
{
matrix
<
rgb_pixel
>
temp
;
find_pyramid_down_output_image_size
(
pyr
,
nr
,
nc
);
pyr
(
pyramid
.
back
(),
temp
);
if
(
nr
*
nc
==
0
||
nr
<
min_height
)
if
(
temp
.
size
()
==
0
||
temp
.
nr
()
<
min_height
)
break
;
break
;
pyramid
.
push_back
(
std
::
move
(
temp
));
rects
.
push_back
(
rectangle
(
nc
,
nr
));
}
}
// figure out output image size
// figure out output image size
long
total_height
=
0
;
long
total_height
=
0
;
for
(
auto
&&
i
:
pyramid
)
for
(
auto
&&
i
:
rects
)
total_height
+=
i
.
nr
()
+
padding
;
total_height
+=
i
.
height
()
+
padding
;
total_height
-=
padding
*
2
;
// don't add unnecessary padding to the very right side.
total_height
-=
padding
*
2
;
// don't add unnecessary padding to the very right side.
long
height
=
0
;
long
height
=
0
;
long
prev_width
=
0
;
long
prev_width
=
0
;
for
(
auto
&&
i
:
pyramid
)
for
(
auto
&&
i
:
rects
)
{
{
// Figure out how far we go on the first column. We go until the next image can
// Figure out how far we go on the first column. We go until the next image can
// fit next to the previous one, which means we can double back for the second
// fit next to the previous one, which means we can double back for the second
// column of images.
// column of images.
if
(
i
.
nc
()
<=
img
.
nc
()
-
prev_width
-
(
long
)
padding
&&
if
(
i
.
width
()
<=
rects
[
0
].
width
()
-
prev_width
-
(
long
)
padding
&&
(
height
-
img
.
nr
())
*
2
>=
(
total_height
-
img
.
nr
()))
(
height
-
rects
[
0
].
height
())
*
2
>=
(
total_height
-
rects
[
0
].
height
()))
{
{
break
;
break
;
}
}
height
+=
i
.
nr
()
+
padding
;
height
+=
i
.
height
()
+
padding
;
prev_width
=
i
.
nc
();
prev_width
=
i
.
width
();
}
}
height
-=
padding
;
// don't add unnecessary padding to the very right side.
height
-=
padding
;
// don't add unnecessary padding to the very right side.
const
long
width
=
img
.
nc
();
const
long
width
=
rects
[
0
].
width
();
set_image_size
(
out_img
,
height
+
outer_padding
*
2
,
width
+
outer_padding
*
2
);
pyramid_image_nr
=
height
+
outer_padding
*
2
;
assign_all_pixels
(
out_img
,
0
);
pyramid_image_nc
=
width
+
outer_padding
*
2
;
long
y
=
outer_padding
;
long
y
=
outer_padding
;
size_t
i
=
0
;
size_t
i
=
0
;
while
(
y
<
height
+
(
long
)
outer_padding
)
while
(
y
<
height
+
(
long
)
outer_padding
&&
i
<
rects
.
size
())
{
{
rectangle
rect
=
translate_rect
(
get_rect
(
pyramid
[
i
]),
point
(
outer_padding
,
y
));
rects
[
i
]
=
translate_rect
(
rects
[
i
],
point
(
outer_padding
,
y
));
DLIB_ASSERT
(
get_rect
(
out_img
).
contains
(
rect
));
DLIB_ASSERT
(
rectangle
(
pyramid_image_nc
,
pyramid_image_nr
).
contains
(
rects
[
i
]));
rects
.
push_back
(
rect
);
y
+=
rects
[
i
].
height
()
+
padding
;
auto
si
=
sub_image
(
out_img
,
rect
);
assign_image
(
si
,
pyramid
[
i
]);
y
+=
pyramid
[
i
].
nr
()
+
padding
;
++
i
;
++
i
;
}
}
y
-=
padding
;
y
-=
padding
;
while
(
i
<
pyramid
.
size
())
while
(
i
<
rects
.
size
())
{
{
point
p1
(
outer_padding
+
width
-
1
,
y
-
1
);
point
p1
(
outer_padding
+
width
-
1
,
y
-
1
);
point
p2
=
p1
-
get_rect
(
pyramid
[
i
]
)
.
br_corner
();
point
p2
=
p1
-
rects
[
i
].
br_corner
();
rectangle
rect
(
p1
,
p2
);
rectangle
rect
(
p1
,
p2
);
DLIB_ASSERT
(
get_rect
(
out_img
).
contains
(
rect
));
DLIB_ASSERT
(
rectangle
(
pyramid_image_nc
,
pyramid_image_nr
).
contains
(
rect
));
// don't keep going on the last row if it would intersect the original image.
// don't keep going on the last row if it would intersect the original image.
if
(
!
get_rect
(
img
)
.
intersect
(
rect
).
is_empty
())
if
(
!
rects
[
0
]
.
intersect
(
rect
).
is_empty
())
break
;
break
;
rects
.
push_back
(
rect
);
auto
si
=
sub_image
(
out_img
,
rect
);
rects
[
i
]
=
rect
;
assign_image
(
si
,
pyramid
[
i
]);
y
-=
rects
[
i
].
height
()
+
padding
;
y
-=
pyramid
[
i
].
nr
()
+
padding
;
++
i
;
++
i
;
}
}
// Delete any extraneous rectangles if we broke out of the above loop early due to
// intersection with the original image.
rects
.
resize
(
i
);
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
pyramid_type
,
typename
image_type1
,
typename
image_type2
>
void
create_tiled_pyramid
(
const
image_type1
&
img
,
image_type2
&
out_img
,
std
::
vector
<
rectangle
>&
rects
,
const
unsigned
long
padding
=
10
,
const
unsigned
long
outer_padding
=
0
)
{
DLIB_ASSERT
(
!
is_same_object
(
img
,
out_img
));
long
out_nr
,
out_nc
;
pyramid_type
pyr
;
impl
::
compute_tiled_image_pyramid_details
(
pyr
,
img
.
nr
(),
img
.
nc
(),
padding
,
outer_padding
,
rects
,
out_nr
,
out_nc
);
set_image_size
(
out_img
,
out_nr
,
out_nc
);
assign_all_pixels
(
out_img
,
0
);
if
(
rects
.
size
()
==
0
)
return
;
// now build the image pyramid into out_img
auto
si
=
sub_image
(
out_img
,
rects
[
0
]);
assign_image
(
si
,
img
);
for
(
size_t
i
=
1
;
i
<
rects
.
size
();
++
i
)
{
auto
s1
=
sub_image
(
out_img
,
rects
[
i
-
1
]);
auto
s2
=
sub_image
(
out_img
,
rects
[
i
]);
pyr
(
s1
,
s2
);
}
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
...
...
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