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
6e9de0db
Commit
6e9de0db
authored
Dec 27, 2013
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added extract_image_chips()
parent
03449af3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
240 additions
and
0 deletions
+240
-0
interpolation.h
dlib/image_transforms/interpolation.h
+121
-0
interpolation_abstract.h
dlib/image_transforms/interpolation_abstract.h
+119
-0
No files found.
dlib/image_transforms/interpolation.h
View file @
6e9de0db
...
...
@@ -1288,6 +1288,127 @@ namespace dlib
pyramid_up
(
img
,
pyr
);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
struct
chip_details
{
chip_details
()
:
size
(
0
),
angle
(
0
)
{}
chip_details
(
const
rectangle
&
rect_
,
unsigned
long
size_
)
:
rect
(
rect_
),
size
(
size_
),
angle
(
0
)
{}
chip_details
(
const
rectangle
&
rect_
,
unsigned
long
size_
,
double
angle_
)
:
rect
(
rect_
),
size
(
size_
),
angle
(
angle_
)
{}
rectangle
rect
;
unsigned
long
size
;
double
angle
;
};
// ----------------------------------------------------------------------------------------
template
<
typename
image_type1
,
typename
image_type2
>
void
extract_image_chips
(
const
image_type1
&
img
,
const
std
::
vector
<
chip_details
>&
chip_locations
,
dlib
::
array
<
image_type2
>&
chips
)
{
// make sure requires clause is not broken
#if ENABLE_ASSERTS
for
(
unsigned
long
i
=
0
;
i
<
chip_locations
.
size
();
++
i
)
{
DLIB_CASSERT
(
chip_locations
[
i
].
size
!=
0
&&
chip_locations
[
i
].
rect
.
is_empty
()
==
false
,
"
\t
void extract_image_chips()"
<<
"
\n\t
Invalid inputs were given to this function."
<<
"
\n\t
chip_locations["
<<
i
<<
"].size: "
<<
chip_locations
[
i
].
size
<<
"
\n\t
chip_locations["
<<
i
<<
"].rect.is_empty(): "
<<
chip_locations
[
i
].
rect
.
is_empty
()
}
#endif
pyramid_down
<
2
>
pyr
;
long
max_depth
=
0
;
// If the chip is supposed to be much smaller than the source subwindow then you
// can't just extract it using bilinear interpolation since at a high enough
// downsampling amount it would effectively turn into nearest neighbor
// interpolation. So we use an image pyramid to make sure the interpolation is
// fast but also high quality. The first thing we do is figure out how deep the
// image pyramid needs to be.
for
(
unsigned
long
i
=
0
;
i
<
chip_locations
.
size
();
++
i
)
{
long
depth
=
0
;
rectangle
rect
=
pyr
.
rect_down
(
chip_locations
[
i
].
rect
);
while
(
rect
.
area
()
>
chip_locations
[
i
].
size
)
{
rect
=
pyr
.
rect_down
(
rect
);
++
depth
;
}
max_depth
=
std
::
max
(
depth
,
max_depth
);
}
// now make an image pyramid
dlib
::
array
<
image_type1
>
levels
(
max_depth
);
if
(
levels
.
size
()
!=
0
)
pyr
(
img
,
levels
[
0
]);
for
(
unsigned
long
i
=
1
;
i
<
levels
.
size
();
++
i
)
pyr
(
levels
[
i
-
1
],
levels
[
i
]);
std
::
vector
<
dlib
::
vector
<
double
,
2
>
>
from
,
to
;
// now pull out the chips
chips
.
resize
(
chip_locations
.
size
());
for
(
unsigned
long
i
=
0
;
i
<
chips
.
size
();
++
i
)
{
const
double
relative_size
=
std
::
sqrt
(
chip_locations
[
i
].
size
/
(
double
)
chip_locations
[
i
].
rect
.
area
());
const
long
chip_height
=
static_cast
<
long
>
(
chip_locations
[
i
].
rect
.
height
()
*
relative_size
+
0
.
5
);
const
long
chip_width
=
static_cast
<
long
>
(
chip_locations
[
i
].
size
/
(
double
)
chip_height
+
0
.
5
);
chips
[
i
].
set_size
(
chip_height
,
chip_width
);
// figure out which level in the pyramid to use to extract the chip
int
level
=
-
1
;
rectangle
rect
=
chip_locations
[
i
].
rect
;
while
(
pyr
.
rect_down
(
rect
).
area
()
>
chip_locations
[
i
].
size
)
{
++
level
;
rect
=
pyr
.
rect_down
(
rect
);
}
// find the appropriate transformation that maps from the chip to the input
// image
from
.
clear
();
to
.
clear
();
from
.
push_back
(
get_rect
(
chips
[
i
]).
tl_corner
());
to
.
push_back
(
rotate_point
<
double
>
(
center
(
rect
),
rect
.
tl_corner
(),
chip_locations
[
i
].
angle
));
from
.
push_back
(
get_rect
(
chips
[
i
]).
tr_corner
());
to
.
push_back
(
rotate_point
<
double
>
(
center
(
rect
),
rect
.
tr_corner
(),
chip_locations
[
i
].
angle
));
from
.
push_back
(
get_rect
(
chips
[
i
]).
bl_corner
());
to
.
push_back
(
rotate_point
<
double
>
(
center
(
rect
),
rect
.
bl_corner
(),
chip_locations
[
i
].
angle
));
point_transform_affine
trns
=
find_affine_transform
(
from
,
to
);
// now extract the actual chip
if
(
level
==
-
1
)
transform_image
(
img
,
chips
[
i
],
interpolate_bilinear
(),
trns
);
else
transform_image
(
levels
[
level
],
chips
[
i
],
interpolate_bilinear
(),
trns
);
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
image_type1
,
typename
image_type2
>
void
extract_image_chip
(
const
image_type1
&
img
,
const
chip_details
&
location
,
image_type2
&
chip
)
{
std
::
vector
<
chip_details
>
chip_locations
(
1
,
location
);
dlib
::
array
<
image_type2
>
chips
;
extract_image_chips
(
img
,
chip_locations
,
chips
);
chips
[
0
].
swap
(
chip
);
}
// ----------------------------------------------------------------------------------------
}
...
...
dlib/image_transforms/interpolation_abstract.h
View file @
6e9de0db
...
...
@@ -786,6 +786,125 @@ namespace dlib
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
struct
chip_details
{
/*!
WHAT THIS OBJECT REPRESENTS
This object describes where an image chip is to be extracted from within
another image. In particular, it specifies that the image chip is
contained within the rectangle this->rect and that prior to extraction the
image should be rotated counter-clockwise by this->angle radians. Finally,
the extracted chip should have this->size pixels in it regardless of the
size of this->rect.
!*/
chip_details
(
);
/*!
ensures
- #rect.is_empty() == true
- #size == 0
- #angle == 0
!*/
chip_details
(
const
rectangle
&
rect_
,
unsigned
long
size_
);
/*!
ensures
- #rect == rect_
- #size == size_
- #angle == 0
!*/
chip_details
(
const
rectangle
&
rect_
,
unsigned
long
size_
,
double
angle_
);
/*!
ensures
- #rect == rect_
- #size == size_
- #angle == angle_
!*/
rectangle
rect
;
unsigned
long
size
;
double
angle
;
};
// ----------------------------------------------------------------------------------------
template
<
typename
image_type1
,
typename
image_type2
>
void
extract_image_chips
(
const
image_type1
&
img
,
const
std
::
vector
<
chip_details
>&
chip_locations
,
dlib
::
array
<
image_type2
>&
chips
);
/*!
requires
- image_type1 == is an implementation of array2d/array2d_kernel_abstract.h
- image_type2 == is an implementation of array2d/array2d_kernel_abstract.h
- pixel_traits<typename image_type1::type>::has_alpha == false
- pixel_traits<typename image_type2::type> is defined
- for all valid i:
- chip_locations[i].rect.is_empty() == false
- chip_locations[i].size != 0
ensures
- This function extracts "chips" from an image. That is, it takes a list of
rectangular sub-windows (i.e. chips) within an image and extracts those
sub-windows, storing each into its own image. It also scales and rotates the
image chips according to the instructions inside each chip_details object.
- #chips == the extracted image chips
- #chips.size() == chip_locations.size()
- for all valid i:
- #chips[i] == The image chip extracted from the position
chip_locations[i].rect in img.
- #chips[i].nr()/#chips[i].nc() is approximately equal to
chip_locations[i].rect.height()/chip_locations[i].rect.width() (i.e. the
aspect ratio of the chip is as similar as possible to the aspect ratio of
the rectangle that defines the chip's location in the original image)
- #chips[i].size() is as close to chip_locations[i].size as possible given that
we attempt to keep the chip's aspect ratio similar to chip_locations[i].rect.
- The image will have been rotated counter-clockwise by
chip_locations[i].angle radians, around the center of
chip_locations[i].rect, before the chip was extracted.
- As long as chip_locations[i].size and the aspect ratio of of
chip_locations[i].rect and stays constant then the dimensions of
#chips[i] is always the same. This means that, for example, if you want
all your chips to have the same dimensions then ensure that
chip_location[i].size is always the same and also that
chip_location[i].rect always has the same aspect ratio.
- Any pixels in an image chip that go outside img are set to 0 (i.e. black).
!*/
// ----------------------------------------------------------------------------------------
template
<
typename
image_type1
,
typename
image_type2
>
void
extract_image_chip
(
const
image_type1
&
img
,
const
chip_details
&
chip_location
,
image_type2
&
chip
);
/*!
ensures
- This function simply calls extract_image_chips() with a single chip location
and stores the single output chip into #chip.
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
}
...
...
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