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
1ab34825
Commit
1ab34825
authored
Dec 27, 2014
by
Davis King
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clarified a few comments and simplified the serialization code a bit.
Also just cleaned up a few minor details.
parent
773fe59a
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
115 additions
and
116 deletions
+115
-116
face_landmark_detection.py
python_examples/face_landmark_detection.py
+9
-5
max_cost_assignment.py
python_examples/max_cost_assignment.py
+2
-3
sequence_segmenter.py
python_examples/sequence_segmenter.py
+14
-12
train_object_detector.py
python_examples/train_object_detector.py
+18
-5
train_shape_predictor.py
python_examples/train_shape_predictor.py
+31
-29
gui.cpp
tools/python/src/gui.cpp
+2
-6
object_detection.cpp
tools/python/src/object_detection.cpp
+3
-2
serialize_object_detector.h
tools/python/src/serialize_object_detector.h
+3
-2
shape_predictor.cpp
tools/python/src/shape_predictor.cpp
+11
-21
shape_predictor.h
tools/python/src/shape_predictor.h
+6
-16
simple_object_detector.h
tools/python/src/simple_object_detector.h
+16
-15
No files found.
python_examples/face_landmark_detection.py
View file @
1ab34825
...
...
@@ -59,16 +59,20 @@ for f in glob.glob(os.path.join(faces_folder_path, "*.jpg")):
win
.
clear_overlay
()
win
.
set_image
(
img
)
# Ask the detector to find the bounding boxes of each face. The 1 in the
# second argument indicates that we should upsample the image 1 time. This
# will make everything bigger and allow us to detect more faces.
dets
=
detector
(
img
,
1
)
print
(
"Number of faces detected: {}"
.
format
(
len
(
dets
)))
for
k
,
d
in
enumerate
(
dets
):
print
(
"Detection {}: Left: {} Top: {} Right: {} Bottom: {}"
.
format
(
k
,
d
.
left
(),
d
.
top
(),
d
.
right
(),
d
.
bottom
()))
shapes
=
predictor
(
img
,
d
)
print
(
"Part 0: {}, Part 1: {} ..."
.
format
(
shapes
.
part
(
0
),
shapes
.
part
(
1
)))
# Add all facial landmarks one at a time
win
.
add_overlay
(
shapes
)
# Get the landmarks/parts for the face in box d.
shape
=
predictor
(
img
,
d
)
print
(
"Part 0: {}, Part 1: {} ..."
.
format
(
shape
.
part
(
0
),
shape
.
part
(
1
)))
# Draw the face landmarks on the screen.
win
.
add_overlay
(
shape
)
win
.
add_overlay
(
dets
)
raw_input
(
"Hit enter to continue"
)
python_examples/max_cost_assignment.py
View file @
1ab34825
...
...
@@ -2,9 +2,8 @@
# The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
#
# This simple example shows how to call dlib's optimal linear assignment
# problem solver.
# It is an implementation of the famous Hungarian algorithm and is quite fast,
# operating in O(N^3) time.
# problem solver. It is an implementation of the famous Hungarian algorithm
# and is quite fast, operating in O(N^3) time.
#
# COMPILING THE DLIB PYTHON INTERFACE
# Dlib comes with a compiled python interface for python 2.7 on MS Windows. If
...
...
python_examples/sequence_segmenter.py
View file @
1ab34825
...
...
@@ -83,45 +83,47 @@ def print_segment(sentence, names):
sys
.
stdout
.
write
(
"
\n
"
)
# Now let's make some training data. Each example is a sentence as well as a
# set of ranges which indicate the locations of any names.
names
=
dlib
.
ranges
()
# make an array of dlib.range objects.
segments
=
dlib
.
rangess
()
# make an array of arrays of dlib.range objects.
sentences
=
[
"The other day I saw a man named Jim Smith"
,
"Davis King is the main author of the dlib Library"
,
"Bob Jones is a name and so is George Clinton"
,
"My dog is named Bob Barker"
,
"ABC is an acronym but John James Smith is a name"
,
"No names in this sentence at all"
]
# set of ranges which indicate the locations of any names.
names
=
dlib
.
ranges
()
# make an array of dlib.range objects.
segments
=
dlib
.
rangess
()
# make an array of arrays of dlib.range objects.
sentences
=
[]
sentences
.
append
(
"The other day I saw a man named Jim Smith"
)
# We want to detect person names. So we note that the name is located within
# the range [8, 10). Note that we use half open ranges to identify segments.
# So in
this case, the segment identifies the string "Jim Smith".
# So in this case, the segment identifies the string "Jim Smith".
names
.
append
(
dlib
.
range
(
8
,
10
))
segments
.
append
(
names
)
# make names empty for use again below
names
.
clear
()
names
.
clear
()
# make names empty for use again below
sentences
.
append
(
"Davis King is the main author of the dlib Library"
)
names
.
append
(
dlib
.
range
(
0
,
2
))
segments
.
append
(
names
)
names
.
clear
()
sentences
.
append
(
"Bob Jones is a name and so is George Clinton"
)
names
.
append
(
dlib
.
range
(
0
,
2
))
names
.
append
(
dlib
.
range
(
8
,
10
))
segments
.
append
(
names
)
names
.
clear
()
sentences
.
append
(
"My dog is named Bob Barker"
)
names
.
append
(
dlib
.
range
(
4
,
6
))
segments
.
append
(
names
)
names
.
clear
()
sentences
.
append
(
"ABC is an acronym but John James Smith is a name"
)
names
.
append
(
dlib
.
range
(
5
,
8
))
segments
.
append
(
names
)
names
.
clear
()
sentences
.
append
(
"No names in this sentence at all"
)
segments
.
append
(
names
)
names
.
clear
()
# Now before we can pass these training sentences to the dlib tools we need to
# convert them into arrays of vectors as discussed above. We can use either a
# sparse or dense representation depending on our needs. In this example, we
...
...
python_examples/train_object_detector.py
View file @
1ab34825
...
...
@@ -36,6 +36,7 @@ if len(sys.argv) != 2:
exit
()
faces_folder
=
sys
.
argv
[
1
]
# Now let's do the training. The train_simple_object_detector() function has a
# bunch of options, all of which come with reasonable default values. The next
# few lines goes over some of these options.
...
...
@@ -55,6 +56,9 @@ options.C = 5
options
.
num_threads
=
4
options
.
be_verbose
=
True
training_xml_path
=
os
.
path
.
join
(
faces_folder
,
"training.xml"
)
testing_xml_path
=
os
.
path
.
join
(
faces_folder
,
"testing.xml"
)
# This function does the actual training. It will save the final detector to
# detector.svm. The input is an XML file that lists the images in the training
# dataset and also contains the positions of the face boxes. To create your
...
...
@@ -63,11 +67,10 @@ options.be_verbose = True
# images with boxes. To see how to use it read the tools/imglab/README.txt
# file. But for this example, we just use the training.xml file included with
# dlib.
training_xml_path
=
os
.
path
.
join
(
faces_folder
,
"training.xml"
)
testing_xml_path
=
os
.
path
.
join
(
faces_folder
,
"testing.xml"
)
dlib
.
train_simple_object_detector
(
training_xml_path
,
"detector.svm"
,
options
)
# Now that we have a face detector we can test it. The first statement tests
# it on the training data. It will print(the precision, recall, and then)
# average precision.
...
...
@@ -80,6 +83,10 @@ print("Training accuracy: {}".format(
print
(
"Testing accuracy: {}"
.
format
(
dlib
.
test_simple_object_detector
(
testing_xml_path
,
"detector.svm"
)))
# Now let's use the detector as you would in a normal application. First we
# will load it from disk.
detector
=
dlib
.
simple_object_detector
(
"detector.svm"
)
...
...
@@ -106,6 +113,12 @@ for f in glob.glob(os.path.join(faces_folder, "*.jpg")):
win
.
add_overlay
(
dets
)
raw_input
(
"Hit enter to continue"
)
# Finally, note that you don't have to use the XML based input to
# train_simple_object_detector(). If you have already loaded your training
# images and bounding boxes for the objects then you can call it as shown
...
...
@@ -126,10 +139,10 @@ boxes_img2 = ([dlib.rectangle(left=154, top=46, right=228, bottom=121),
boxes
=
[
boxes_img1
,
boxes_img2
]
detector2
=
dlib
.
train_simple_object_detector
(
images
,
boxes
,
options
)
# We could save this detector
by uncommenting the following
# We could save this detector
to disk by uncommenting the following.
#detector2.save('detector2.svm')
# Now let's lo
ad the trained detector and lo
ok at its HOG filter!
# Now let's look at its HOG filter!
win_det
.
set_image
(
detector2
)
raw_input
(
"Hit enter to continue"
)
...
...
python_examples/train_shape_predictor.py
View file @
1ab34825
...
...
@@ -8,7 +8,7 @@
# In particular, we will train a face landmarking model based on a small
# dataset and then evaluate it. If you want to visualize the output of the
# trained model on some images then you can run the
# face_landmark_detection.py example program with
sp
.dat as the input
# face_landmark_detection.py example program with
predictor
.dat as the input
# model.
#
# It should also be noted that this kind of model, while often used for face
...
...
@@ -49,7 +49,7 @@ options = dlib.shape_predictor_training_options()
# Now make the object responsible for training the model.
# This algorithm has a bunch of parameters you can mess with. The
# documentation for the shape_predictor_trainer explains all of them.
# You should also read Kazemi paper which explains all the parameters
# You should also read Kazemi
's
paper which explains all the parameters
# in great detail. However, here I'm just setting three of them
# differently than their default values. I'm doing this because we
# have a very small dataset. In particular, setting the oversampling
...
...
@@ -63,33 +63,35 @@ options.nu = 0.05
options
.
tree_depth
=
2
options
.
be_verbose
=
True
# This function does the actual training. It will save the final predictor to
# predictor.dat. The input is an XML file that lists the images in the training
# dataset and also contains the positions of the face parts.
# dlib.train_shape_predictor() does the actual training. It will save the
# final predictor to predictor.dat. The input is an XML file that lists the
# images in the training dataset and also contains the positions of the face
# parts.
training_xml_path
=
os
.
path
.
join
(
faces_folder
,
"training_with_face_landmarks.xml"
)
testing_xml_path
=
os
.
path
.
join
(
faces_folder
,
"testing_with_face_landmarks.xml"
)
dlib
.
train_shape_predictor
(
training_xml_path
,
"predictor.dat"
,
options
)
# Now that we have a
facial landmark predictor we can test it. The first
#
statement tests it on the training data. It will print the mean average error
print
(
""
)
# Print blank line to create gap from previous output
print
(
"Training accuracy: {}"
.
format
(
# Now that we have a
model we can test it. dlib.test_shape_predictor()
#
measures the average distance between a face landmark output by the
# shape_predictor and where it should be according to the truth data.
print
(
"
\n
Training accuracy: {}"
.
format
(
dlib
.
test_shape_predictor
(
training_xml_path
,
"predictor.dat"
)))
# However, to get an idea if it really worked without overfitting we need to
# run it on images it wasn't trained on. The next line does this. Happily, we
# see that the object detector works perfectly on the testing images.
# The real test is to see how well it does on data it wasn't trained on. We
# trained it on a very small dataset so the accuracy is not extremely high, but
# it's still doing quite good. Moreover, if you train it on one of the large
# face landmarking datasets you will obtain state-of-the-art results, as shown
# in the Kazemi paper.
testing_xml_path
=
os
.
path
.
join
(
faces_folder
,
"testing_with_face_landmarks.xml"
)
print
(
"Testing accuracy: {}"
.
format
(
dlib
.
test_shape_predictor
(
testing_xml_path
,
"predictor.dat"
)))
# Now let's use the detector as you would in a normal application. First we
# will load it from disk. We also need to load a face detector to provide the
# initial estimate of the facial location
detector
=
dlib
.
get_frontal_face_detector
()
# Now let's it as you would in a normal application. First we will load it
# from disk. We also need to load a face detector to provide the initial
# estimate of the facial location.
predictor
=
dlib
.
shape_predictor
(
"predictor.dat"
)
detector
=
dlib
.
get_frontal_face_detector
()
# Now let's run the detector and
predictor over the images in the faces folder
# and display the results.
# Now let's run the detector and
shape_predictor over the images in the faces
#
folder
and display the results.
print
(
"Showing detections and predictions on the images in the faces folder..."
)
win
=
dlib
.
image_window
()
for
f
in
glob
.
glob
(
os
.
path
.
join
(
faces_folder
,
"*.jpg"
)):
...
...
@@ -99,21 +101,21 @@ for f in glob.glob(os.path.join(faces_folder, "*.jpg")):
win
.
clear_overlay
()
win
.
set_image
(
img
)
# Ask the detector to find the bounding boxes of each face. The 1 in the
# second argument indicates that we should upsample the image 1 time. This
# will make everything bigger and allow us to detect more faces.
dets
=
detector
(
img
,
1
)
print
(
"Number of faces detected: {}"
.
format
(
len
(
dets
)))
for
k
,
d
in
enumerate
(
dets
):
print
(
"Detection {}: Left: {} Top: {} Right: {} Bottom: {}"
.
format
(
k
,
d
.
left
(),
d
.
top
(),
d
.
right
(),
d
.
bottom
()))
shapes
=
predictor
(
img
,
d
)
print
(
"Part 0: {}, Part 1: {} ..."
.
format
(
shapes
.
part
(
0
),
shapes
.
part
(
1
)))
# Add all facial landmarks one at a time
win
.
add_overlay
(
shapes
)
# Get the landmarks/parts for the face in box d.
shape
=
predictor
(
img
,
d
)
print
(
"Part 0: {}, Part 1: {} ..."
.
format
(
shape
.
part
(
0
),
shape
.
part
(
1
)))
# Draw the face landmarks on the screen.
win
.
add_overlay
(
shape
)
win
.
add_overlay
(
dets
)
raw_input
(
"Hit enter to continue"
)
# Finally, note that you don't have to use the XML based input to
# train_shape_predictor(). If you have already loaded your training
# images and fll_object_detections for the objects then you can call it with
# the existing objects.
tools/python/src/gui.cpp
View file @
1ab34825
...
...
@@ -51,9 +51,7 @@ void add_overlay_rect (
const
rgb_pixel
&
color
)
{
std
::
vector
<
rectangle
>
rects
;
rects
.
push_back
(
rect
);
win
.
add_overlay
(
rects
,
color
);
win
.
add_overlay
(
rect
,
color
);
}
void
add_overlay_parts
(
...
...
@@ -62,9 +60,7 @@ void add_overlay_parts (
const
rgb_pixel
&
color
)
{
std
::
vector
<
full_object_detection
>
detections
;
detections
.
push_back
(
detection
);
win
.
add_overlay
(
render_face_detections
(
detections
,
color
));
win
.
add_overlay
(
render_face_detections
(
detection
,
color
));
}
boost
::
shared_ptr
<
image_window
>
make_image_window_from_image
(
object
img
)
...
...
tools/python/src/object_detection.cpp
View file @
1ab34825
...
...
@@ -257,8 +257,9 @@ ensures \n\
class_
<
type
>
(
"fhog_object_detector"
,
"This object represents a sliding window histogram-of-oriented-gradients based object detector."
)
.
def
(
"__init__"
,
make_constructor
(
&
load_object_from_file
<
type
>
),
"Loads a simple_object_detector from a file that contains the output of the
\n
\
train_simple_object_detector() routine."
)
"Loads an object detector from a file that contains the output of the
\n
\
train_simple_object_detector() routine or a serialized C++ object of type
\n
\
object_detector<scan_fhog_pyramid<pyramid_down<6>>>."
)
.
def
(
"__call__"
,
run_detector_with_upscale
,
(
arg
(
"image"
),
arg
(
"upsample_num_times"
)
=
0
),
"requires
\n
\
- image is a numpy ndarray containing either an 8bit grayscale or RGB
\n
\
...
...
tools/python/src/serialize_object_detector.h
View file @
1ab34825
...
...
@@ -39,9 +39,10 @@ namespace dlib
inline
void
save_simple_object_detector
(
const
simple_object_detector
&
detector
,
const
std
::
string
&
detector_output_filename
)
{
std
::
ofstream
fout
(
detector_output_filename
.
c_str
(),
std
::
ios
::
binary
);
int
version
=
1
;
serialize
(
detector
,
fout
);
serialize
(
version
,
fout
);
// Don't need to save version of upsampling amount because want to write out the
// object detector just like the C++ code that serializes an object_detector would.
// We also don't know the upsampling amount in this case anyway.
}
}
...
...
tools/python/src/shape_predictor.cpp
View file @
1ab34825
...
...
@@ -38,9 +38,7 @@ full_object_detection run_predictor (
void
save_shape_predictor
(
const
shape_predictor
&
predictor
,
const
std
::
string
&
predictor_output_filename
)
{
std
::
ofstream
fout
(
predictor_output_filename
.
c_str
(),
std
::
ios
::
binary
);
int
version
=
1
;
serialize
(
predictor
,
fout
);
serialize
(
version
,
fout
);
}
// ----------------------------------------------------------------------------------------
...
...
@@ -95,7 +93,7 @@ inline shape_predictor train_shape_predictor_on_images_py (
throw
dlib
::
error
(
"The length of the detections list must match the length of the images list."
);
std
::
vector
<
std
::
vector
<
full_object_detection
>
>
detections
(
num_images
);
dlib
::
array
<
array2d
<
rgb_pixel
>
>
images
(
num_images
);
dlib
::
array
<
array2d
<
unsigned
char
>
>
images
(
num_images
);
images_and_nested_params_to_dlib
(
pyimages
,
pydetections
,
images
,
detections
);
return
train_shape_predictor_on_images
(
images
,
detections
,
options
);
...
...
@@ -121,9 +119,9 @@ inline double test_shape_predictor_with_images_py (
std
::
vector
<
std
::
vector
<
double
>
>
scales
;
if
(
num_scales
>
0
)
scales
.
resize
(
num_scales
);
dlib
::
array
<
array2d
<
rgb_pixel
>
>
images
(
num_images
);
dlib
::
array
<
array2d
<
unsigned
char
>
>
images
(
num_images
);
// Now copy the data into dlib based objects so we can call the t
rainer
.
// Now copy the data into dlib based objects so we can call the t
esting routine
.
for
(
unsigned
long
i
=
0
;
i
<
num_images
;
++
i
)
{
const
unsigned
long
num_boxes
=
len
(
pydetections
[
i
]);
...
...
@@ -193,7 +191,7 @@ void bind_shape_predictors()
&
type
::
nu
,
"The regularization parameter. Larger values of this parameter \
will cause the algorithm to fit the training data better but may also \
cause overfitting."
)
cause overfitting.
The value must be in the range (0, 1].
"
)
.
add_property
(
"oversampling_amount"
,
&
type
::
oversampling_amount
,
&
type
::
oversampling_amount
,
"The number of randomly selected initial starting points sampled for each training example"
)
...
...
@@ -232,7 +230,7 @@ train_shape_predictor() routine.")
- box is the bounding box to begin the shape prediction inside.
\n
\
ensures
\n
\
- This function runs the shape predictor on the input image and returns
\n
\
a single full
object
detection."
)
a single full
_object_
detection."
)
.
def
(
"save"
,
save_shape_predictor
,
(
arg
(
"predictor_output_filename"
)),
"Save a shape_predictor to the provided path."
)
.
def_pickle
(
serialize_pickle
<
type
>
());
}
...
...
@@ -241,36 +239,28 @@ ensures \n\
(
arg
(
"images"
),
arg
(
"object_detections"
),
arg
(
"options"
)),
"requires
\n
\
- options.lambda > 0
\n
\
-
options.nu > 0
\n
\
-
0 < options.nu <= 1
\n
\
- options.feature_pool_region_padding >= 0
\n
\
- len(images) == len(object_detections)
\n
\
- images should be a list of numpy matrices that represent images, either RGB or grayscale.
\n
\
- object_detections should be a list of lists of dlib.full_object_detection objects. \
Each dlib.full_object_detection contains the bounding box and the lists of points that make up the object parts.
\n
\
ensures
\n
\
- Uses the shape_predictor_trainer to train a
\n
\
shape_predictor based on the provided labeled images and full object detections.
\n
\
- This function will apply a reasonable set of default parameters and
\n
\
preprocessing techniques to the training procedure for shape_predictors
\n
\
objects. So the point of this function is to provide you with a very easy
\n
\
way to train a basic shape predictor.
\n
\
- Uses dlib's shape_predictor_trainer object to train a
\n
\
shape_predictor based on the provided labeled images, full_object_detections, and options.
\n
\
- The trained shape_predictor is returned"
);
def
(
"train_shape_predictor"
,
train_shape_predictor
,
(
arg
(
"dataset_filename"
),
arg
(
"predictor_output_filename"
),
arg
(
"options"
)),
"requires
\n
\
- options.lambda > 0
\n
\
-
options.nu > 0
\n
\
-
0 < options.nu <= 1
\n
\
- options.feature_pool_region_padding >= 0
\n
\
ensures
\n
\
- Uses
the
shape_predictor_trainer to train a
\n
\
- Uses
dlib's
shape_predictor_trainer to train a
\n
\
shape_predictor based on the labeled images in the XML file
\n
\
dataset_filename. This function assumes the file dataset_filename is in the
\n
\
dataset_filename
and the provided options
. This function assumes the file dataset_filename is in the
\n
\
XML format produced by dlib's save_image_dataset_metadata() routine.
\n
\
- This function will apply a reasonable set of default parameters and
\n
\
preprocessing techniques to the training procedure for shape_predictors
\n
\
objects. So the point of this function is to provide you with a very easy
\n
\
way to train a basic shape predictor.
\n
\
- The trained shape predictor is serialized to the file predictor_output_filename."
);
def
(
"test_shape_predictor"
,
test_shape_predictor_py
,
...
...
tools/python/src/shape_predictor.h
View file @
1ab34825
...
...
@@ -73,8 +73,8 @@ namespace dlib
{
if
(
options
.
lambda
<=
0
)
throw
error
(
"Invalid lambda value given to train_shape_predictor(), lambda must be > 0."
);
if
(
options
.
nu
<=
0
)
throw
error
(
"Invalid nu value given to train_shape_predictor()
, nu must be > 0
."
);
if
(
!
(
0
<
options
.
nu
&&
options
.
nu
<=
1
)
)
throw
error
(
"Invalid nu value given to train_shape_predictor()
. It is required that 0 < nu <= 1
."
);
if
(
options
.
feature_pool_region_padding
<
0
)
throw
error
(
"Invalid feature_pool_region_padding value given to train_shape_predictor(), feature_pool_region_padding must be >= 0."
);
...
...
@@ -123,16 +123,13 @@ namespace dlib
const
shape_predictor_training_options
&
options
)
{
dlib
::
array
<
array2d
<
rgb_pixel
>
>
images
;
dlib
::
array
<
array2d
<
unsigned
char
>
>
images
;
std
::
vector
<
std
::
vector
<
full_object_detection
>
>
objects
;
load_image_dataset
(
images
,
objects
,
dataset_filename
);
shape_predictor
predictor
=
train_shape_predictor_on_images
(
images
,
objects
,
options
);
std
::
ofstream
fout
(
predictor_output_filename
.
c_str
(),
std
::
ios
::
binary
);
int
version
=
1
;
serialize
(
predictor
,
fout
);
serialize
(
version
,
fout
);
serialize
(
predictor_output_filename
)
<<
predictor
;
if
(
options
.
be_verbose
)
std
::
cout
<<
"Training complete, saved predictor to file "
<<
predictor_output_filename
<<
std
::
endl
;
...
...
@@ -165,7 +162,7 @@ namespace dlib
)
{
// Load the images, no scales can be provided
dlib
::
array
<
array2d
<
rgb_pixel
>
>
images
;
dlib
::
array
<
array2d
<
unsigned
char
>
>
images
;
// This interface cannot take the scales parameter.
std
::
vector
<
std
::
vector
<
double
>
>
scales
;
std
::
vector
<
std
::
vector
<
full_object_detection
>
>
objects
;
...
...
@@ -173,14 +170,7 @@ namespace dlib
// Load the shape predictor
shape_predictor
predictor
;
int
version
=
0
;
std
::
ifstream
fin
(
predictor_filename
.
c_str
(),
std
::
ios
::
binary
);
if
(
!
fin
)
throw
error
(
"Unable to open file "
+
predictor_filename
);
deserialize
(
predictor
,
fin
);
deserialize
(
version
,
fin
);
if
(
version
!=
1
)
throw
error
(
"Unknown shape_predictor format."
);
deserialize
(
predictor_filename
)
>>
predictor
;
return
test_shape_predictor_with_images
(
images
,
objects
,
scales
,
predictor
);
}
...
...
tools/python/src/simple_object_detector.h
View file @
1ab34825
...
...
@@ -276,32 +276,33 @@ namespace dlib
// Load the detector off disk (We have to use the explicit serialization here
// so that we have an open file stream)
simple_object_detector
detector
;
int
version
=
0
;
std
::
ifstream
fin
(
detector_filename
.
c_str
(),
std
::
ios
::
binary
);
if
(
!
fin
)
throw
error
(
"Unable to open file "
+
detector_filename
);
deserialize
(
detector
,
fin
);
deserialize
(
version
,
fin
);
if
(
version
!=
1
)
throw
error
(
"Unknown simple_object_detector format."
);
/* Here we need a little hack to deal with whether we are going to be loading a
* simple_object_detector (possibly trained outside of Python) or a
* simple_object_detector_py (definitely trained from Python). In order to do
* this we peek into the filestream to see if there is more data after the
* version number. If there is, it will be the upsampling amount. Therefore,
* by default we set the upsampling amount to -1 so that we can catch when
* no upsampling amount has been passed (numbers less than 0). If -1 is
* passed, we assume no upsampling and use 0. If a number > 0 is passed,
* we use that, else we use the upsampling amount cached with the detector
* (if it exists).
* simple_object_detector_py (definitely trained from Python). In order to do this
* we peek into the filestream to see if there is more data after the object
* detector. If there is, it will be the version and upsampling amount. Therefore,
* by default we set the upsampling amount to -1 so that we can catch when no
* upsampling amount has been passed (numbers less than 0). If -1 is passed, we
* assume no upsampling and use 0. If a number > 0 is passed, we use that, else we
* use the upsampling amount saved in the detector file (if it exists).
*/
unsigned
int
final_upsampling_amount
=
0
;
const
unsigned
int
cached_upsample_amount
=
fin
.
peek
();
if
(
fin
.
peek
()
!=
EOF
)
{
int
version
=
0
;
deserialize
(
version
,
fin
);
if
(
version
!=
1
)
throw
error
(
"Unknown simple_object_detector format."
);
deserialize
(
final_upsampling_amount
,
fin
);
}
if
(
upsample_amount
>=
0
)
final_upsampling_amount
=
upsample_amount
;
else
if
(
cached_upsample_amount
!=
std
::
char_traits
<
wchar_t
>::
eof
())
// peek() returns EOF if no more data
deserialize
(
final_upsampling_amount
,
fin
);
return
test_simple_object_detector_with_images
(
images
,
final_upsampling_amount
,
boxes
,
ignore
,
detector
);
}
...
...
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