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
09974608
Commit
09974608
authored
Jul 04, 2016
by
Davis King
Browse files
Added --extract-chips option to imglab.
parent
27440b6c
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
138 additions
and
2 deletions
+138
-2
tools/imglab/src/main.cpp
tools/imglab/src/main.cpp
+138
-2
No files found.
tools/imglab/src/main.cpp
View file @
09974608
...
@@ -377,6 +377,128 @@ void rotate_dataset(const command_line_parser& parser)
...
@@ -377,6 +377,128 @@ void rotate_dataset(const command_line_parser& parser)
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
int
extract_chips
(
const
command_line_parser
&
parser
)
{
if
(
parser
.
number_of_arguments
()
!=
1
)
{
cerr
<<
"The --extract-chips option requires you to give one XML file on the command line."
<<
endl
;
return
EXIT_FAILURE
;
}
const
size_t
obj_size
=
get_option
(
parser
,
"extract-chips"
,
100
*
100
);
dlib
::
image_dataset_metadata
::
dataset
data
;
load_image_dataset_metadata
(
data
,
parser
[
0
]);
// figure out the average box size so we can make all the chips have the same exact
// dimensions
running_stats
<
double
>
rs
;
for
(
auto
&&
img
:
data
.
images
)
{
for
(
auto
&&
box
:
img
.
boxes
)
{
if
(
box
.
rect
.
height
()
!=
0
)
rs
.
add
(
box
.
rect
.
width
()
/
(
double
)
box
.
rect
.
height
());
}
}
if
(
rs
.
current_n
()
==
0
)
{
cerr
<<
"Dataset doesn't contain any non-empty and non-ignored boxes!"
<<
endl
;
return
EXIT_FAILURE
;
}
const
double
dobj_nr
=
std
::
sqrt
(
obj_size
/
rs
.
mean
());
const
double
dobj_nc
=
obj_size
/
dobj_nr
;
const
chip_dims
cdims
(
std
::
round
(
dobj_nr
),
std
::
round
(
dobj_nc
));
locally_change_current_dir
chdir
(
get_parent_directory
(
file
(
parser
[
0
])));
cout
<<
"Writing image chips to image_chips.dat. It is a file containing serialized images"
<<
endl
;
cout
<<
"Written like this: "
<<
endl
;
cout
<<
" ofstream fout(
\"
image_chips.dat
\"
, ios::bianry); "
<<
endl
;
cout
<<
" bool is_not_background; "
<<
endl
;
cout
<<
" array2d<rgb_pixel> the_image_chip; "
<<
endl
;
cout
<<
" while(more images) { "
<<
endl
;
cout
<<
" ... load chip ... "
<<
endl
;
cout
<<
" serialize(is_not_background, fout);"
<<
endl
;
cout
<<
" serialize(the_image_chip, fout);"
<<
endl
;
cout
<<
" }"
<<
endl
;
cout
<<
endl
;
ofstream
fout
(
"image_chips.dat"
,
ios
::
binary
);
dlib
::
rand
rnd
;
unsigned
long
count
=
0
;
console_progress_indicator
pbar
(
data
.
images
.
size
());
for
(
unsigned
long
i
=
0
;
i
<
data
.
images
.
size
();
++
i
)
{
// don't even bother loading images that don't have objects.
if
(
data
.
images
[
i
].
boxes
.
size
()
==
0
)
continue
;
pbar
.
print_status
(
i
);
array2d
<
rgb_pixel
>
img
,
chip
;
load_image
(
img
,
data
.
images
[
i
].
filename
);
std
::
vector
<
chip_details
>
chips
;
std
::
vector
<
rectangle
>
used_rects
;
for
(
unsigned
long
j
=
0
;
j
<
data
.
images
[
i
].
boxes
.
size
();
++
j
)
{
const
rectangle
rect
=
data
.
images
[
i
].
boxes
[
j
].
rect
;
used_rects
.
push_back
(
rect
);
if
(
data
.
images
[
i
].
boxes
[
j
].
ignore
)
continue
;
chips
.
push_back
(
chip_details
(
rect
,
cdims
));
}
const
auto
num_good_chps
=
chips
.
size
();
// Now grab some bad chips, being careful not to grab things that overlap with
// annotated boxes in the dataset.
for
(
unsigned
long
j
=
0
;
j
<
num_good_chps
*
5
;
++
j
)
{
// pick two random points that make a box of the correct aspect ratio
// pick a point so that our rectangle will fit within the
point
p1
(
rnd
.
get_random_32bit_number
()
%
img
.
nc
(),
rnd
.
get_random_32bit_number
()
%
img
.
nr
());
// make the random box between 0.5 and 1.5 times the size of the truth boxes.
double
box_size
=
rnd
.
get_random_double
()
+
0.5
;
point
p2
=
p1
+
point
(
dobj_nc
*
box_size
,
dobj_nr
*
box_size
);
rectangle
rect
(
p1
,
p2
);
if
(
overlaps_any_box
(
used_rects
,
rect
)
||
!
get_rect
(
img
).
contains
(
rect
))
continue
;
used_rects
.
push_back
(
rect
);
chips
.
push_back
(
chip_details
(
rect
,
cdims
));
}
// now save these chips to disk.
dlib
::
array
<
array2d
<
rgb_pixel
>>
image_chips
;
extract_image_chips
(
img
,
chips
,
image_chips
);
bool
is_not_background
=
true
;
unsigned
long
j
;
for
(
j
=
0
;
j
<
num_good_chps
;
++
j
)
{
serialize
(
is_not_background
,
fout
);
serialize
(
image_chips
[
j
],
fout
);
}
is_not_background
=
false
;
for
(;
j
<
image_chips
.
size
();
++
j
)
{
serialize
(
is_not_background
,
fout
);
serialize
(
image_chips
[
j
],
fout
);
}
count
+=
image_chips
.
size
();
}
cout
<<
"
\n
Saved "
<<
count
<<
" chips."
<<
endl
;
return
EXIT_SUCCESS
;
}
// ----------------------------------------------------------------------------------------
int
resample_dataset
(
const
command_line_parser
&
parser
)
int
resample_dataset
(
const
command_line_parser
&
parser
)
{
{
if
(
parser
.
number_of_arguments
()
!=
1
)
if
(
parser
.
number_of_arguments
()
!=
1
)
...
@@ -572,12 +694,14 @@ int main(int argc, char** argv)
...
@@ -572,12 +694,14 @@ int main(int argc, char** argv)
parser
.
add_option
(
"cluster"
,
"Cluster all the objects in an XML file into <arg> different clusters and save "
parser
.
add_option
(
"cluster"
,
"Cluster all the objects in an XML file into <arg> different clusters and save "
"the results as cluster_###.xml and cluster_###.jpg files."
,
1
);
"the results as cluster_###.xml and cluster_###.jpg files."
,
1
);
parser
.
add_option
(
"resample"
,
"Crop out images that are centered on each object in the dataset. Make the "
parser
.
add_option
(
"resample"
,
"Crop out images that are centered on each object in the dataset. Make the "
"crops so that the objects have <arg> pixels in them."
,
1
);
"crops so that the objects have <arg> pixels in them. The output is a new XML dataset."
,
1
);
parser
.
add_option
(
"extract-chips"
,
"Crops out images with tight bounding boxes around each object. Also crops out "
"many background chips. All these image chips are serialized into one big data file. The chips will contain <arg> pixels each"
,
1
);
parser
.
parse
(
argc
,
argv
);
parser
.
parse
(
argc
,
argv
);
const
char
*
singles
[]
=
{
"h"
,
"c"
,
"r"
,
"l"
,
"convert"
,
"parts"
,
"rmdiff"
,
"rmtrunc"
,
"rmdupes"
,
"seed"
,
"shuffle"
,
"split"
,
"add"
,
const
char
*
singles
[]
=
{
"h"
,
"c"
,
"r"
,
"l"
,
"convert"
,
"parts"
,
"rmdiff"
,
"rmtrunc"
,
"rmdupes"
,
"seed"
,
"shuffle"
,
"split"
,
"add"
,
"flip"
,
"rotate"
,
"tile"
,
"size"
,
"cluster"
,
"resample"
};
"flip"
,
"rotate"
,
"tile"
,
"size"
,
"cluster"
,
"resample"
,
"extract-chips"
};
parser
.
check_one_time_options
(
singles
);
parser
.
check_one_time_options
(
singles
);
const
char
*
c_sub_ops
[]
=
{
"r"
,
"convert"
};
const
char
*
c_sub_ops
[]
=
{
"r"
,
"convert"
};
parser
.
check_sub_options
(
"c"
,
c_sub_ops
);
parser
.
check_sub_options
(
"c"
,
c_sub_ops
);
...
@@ -596,6 +720,7 @@ int main(int argc, char** argv)
...
@@ -596,6 +720,7 @@ int main(int argc, char** argv)
parser
.
check_incompatible_options
(
"c"
,
"tile"
);
parser
.
check_incompatible_options
(
"c"
,
"tile"
);
parser
.
check_incompatible_options
(
"c"
,
"cluster"
);
parser
.
check_incompatible_options
(
"c"
,
"cluster"
);
parser
.
check_incompatible_options
(
"c"
,
"resample"
);
parser
.
check_incompatible_options
(
"c"
,
"resample"
);
parser
.
check_incompatible_options
(
"c"
,
"extract-chips"
);
parser
.
check_incompatible_options
(
"l"
,
"rename"
);
parser
.
check_incompatible_options
(
"l"
,
"rename"
);
parser
.
check_incompatible_options
(
"l"
,
"add"
);
parser
.
check_incompatible_options
(
"l"
,
"add"
);
parser
.
check_incompatible_options
(
"l"
,
"parts"
);
parser
.
check_incompatible_options
(
"l"
,
"parts"
);
...
@@ -608,18 +733,23 @@ int main(int argc, char** argv)
...
@@ -608,18 +733,23 @@ int main(int argc, char** argv)
parser
.
check_incompatible_options
(
"rotate"
,
"tile"
);
parser
.
check_incompatible_options
(
"rotate"
,
"tile"
);
parser
.
check_incompatible_options
(
"cluster"
,
"tile"
);
parser
.
check_incompatible_options
(
"cluster"
,
"tile"
);
parser
.
check_incompatible_options
(
"resample"
,
"tile"
);
parser
.
check_incompatible_options
(
"resample"
,
"tile"
);
parser
.
check_incompatible_options
(
"extract-chips"
,
"tile"
);
parser
.
check_incompatible_options
(
"flip"
,
"cluster"
);
parser
.
check_incompatible_options
(
"flip"
,
"cluster"
);
parser
.
check_incompatible_options
(
"rotate"
,
"cluster"
);
parser
.
check_incompatible_options
(
"rotate"
,
"cluster"
);
parser
.
check_incompatible_options
(
"add"
,
"cluster"
);
parser
.
check_incompatible_options
(
"add"
,
"cluster"
);
parser
.
check_incompatible_options
(
"flip"
,
"resample"
);
parser
.
check_incompatible_options
(
"flip"
,
"resample"
);
parser
.
check_incompatible_options
(
"rotate"
,
"resample"
);
parser
.
check_incompatible_options
(
"rotate"
,
"resample"
);
parser
.
check_incompatible_options
(
"add"
,
"resample"
);
parser
.
check_incompatible_options
(
"add"
,
"resample"
);
parser
.
check_incompatible_options
(
"flip"
,
"extract-chips"
);
parser
.
check_incompatible_options
(
"rotate"
,
"extract-chips"
);
parser
.
check_incompatible_options
(
"add"
,
"extract-chips"
);
parser
.
check_incompatible_options
(
"shuffle"
,
"tile"
);
parser
.
check_incompatible_options
(
"shuffle"
,
"tile"
);
parser
.
check_incompatible_options
(
"convert"
,
"l"
);
parser
.
check_incompatible_options
(
"convert"
,
"l"
);
parser
.
check_incompatible_options
(
"convert"
,
"rename"
);
parser
.
check_incompatible_options
(
"convert"
,
"rename"
);
parser
.
check_incompatible_options
(
"convert"
,
"parts"
);
parser
.
check_incompatible_options
(
"convert"
,
"parts"
);
parser
.
check_incompatible_options
(
"convert"
,
"cluster"
);
parser
.
check_incompatible_options
(
"convert"
,
"cluster"
);
parser
.
check_incompatible_options
(
"convert"
,
"resample"
);
parser
.
check_incompatible_options
(
"convert"
,
"resample"
);
parser
.
check_incompatible_options
(
"convert"
,
"extract-chips"
);
parser
.
check_incompatible_options
(
"rmdiff"
,
"rename"
);
parser
.
check_incompatible_options
(
"rmdiff"
,
"rename"
);
parser
.
check_incompatible_options
(
"rmdupes"
,
"rename"
);
parser
.
check_incompatible_options
(
"rmdupes"
,
"rename"
);
parser
.
check_incompatible_options
(
"rmtrunc"
,
"rename"
);
parser
.
check_incompatible_options
(
"rmtrunc"
,
"rename"
);
...
@@ -629,6 +759,7 @@ int main(int argc, char** argv)
...
@@ -629,6 +759,7 @@ int main(int argc, char** argv)
parser
.
check_option_arg_range
(
"rotate"
,
-
360
,
360
);
parser
.
check_option_arg_range
(
"rotate"
,
-
360
,
360
);
parser
.
check_option_arg_range
(
"size"
,
10
*
10
,
1000
*
1000
);
parser
.
check_option_arg_range
(
"size"
,
10
*
10
,
1000
*
1000
);
parser
.
check_option_arg_range
(
"resample"
,
4
,
1000
*
1000
);
parser
.
check_option_arg_range
(
"resample"
,
4
,
1000
*
1000
);
parser
.
check_option_arg_range
(
"extract-chips"
,
4
,
1000
*
1000
);
if
(
parser
.
option
(
"h"
))
if
(
parser
.
option
(
"h"
))
{
{
...
@@ -680,6 +811,11 @@ int main(int argc, char** argv)
...
@@ -680,6 +811,11 @@ int main(int argc, char** argv)
return
resample_dataset
(
parser
);
return
resample_dataset
(
parser
);
}
}
if
(
parser
.
option
(
"extract-chips"
))
{
return
extract_chips
(
parser
);
}
if
(
parser
.
option
(
"c"
))
if
(
parser
.
option
(
"c"
))
{
{
if
(
parser
.
option
(
"convert"
))
if
(
parser
.
option
(
"convert"
))
...
...
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