Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bob
bob.bio.face
Commits
5432f7a1
Commit
5432f7a1
authored
Jan 25, 2018
by
Amir MOHAMMADI
Browse files
Finalize the annotate API
parent
9b7a7607
Changes
7
Hide whitespace changes
Inline
Side-by-side
bob/bio/face/annotator/Base.py
View file @
5432f7a1
...
...
@@ -9,17 +9,20 @@ class Base(object):
self
.
read_original_data
=
read_original_data
or
base_read
def
annotate
(
self
,
image
,
**
kwargs
):
"""Annotates an image and returns annotations in a dictionary
"""Annotates an image and returns annotations in a dictionary.
All annotator should return at least the topleft and bottomright
coordinates.
Parameters
----------
image : object
The image is what comes out of ``read_original_data``.
image : array
The image should be a Bob format (#Channels, Height, Width) RGB
image.
**kwargs
The extra arguments that may be passed.
"""
raise
NotImplementedError
()
# Alisa call to annotate
__call__
=
annotate
__call__
.
__doc__
=
annotate
.
__doc__
def
__call__
(
self
,
image
,
**
kwargs
):
return
self
.
annotate
(
image
,
**
kwargs
)
bob/bio/face/annotator/FailSafe.py
View file @
5432f7a1
...
...
@@ -17,7 +17,7 @@ class FailSafe(Base):
self
.
required_keys
=
list
(
required_keys
)
def
annotate
(
self
,
image
,
**
kwargs
):
if
'annotations'
not
in
kwargs
:
if
'annotations'
not
in
kwargs
or
kwargs
[
'annotations'
]
is
None
:
kwargs
[
'annotations'
]
=
{}
for
annotator
in
self
.
annotators
:
try
:
...
...
@@ -27,6 +27,9 @@ class FailSafe(Base):
"The annotator `%s' failed to annotate!"
,
annotator
,
exc_info
=
True
)
annotations
=
{}
if
not
annotations
:
logger
.
debug
(
"Annotator `%s' returned empty annotations."
,
annotator
)
kwargs
[
'annotations'
].
update
(
annotations
)
# check if we have all the required annotations
if
all
(
key
in
kwargs
[
'annotations'
]
for
key
in
self
.
required_keys
):
...
...
bob/bio/face/annotator/__init__.py
View file @
5432f7a1
from
.Base
import
Base
from
.FailSafe
import
FailSafe
def
bounding_box_to_annotations
(
bbx
):
...
...
bob/bio/face/annotator/bobipfacedetect.py
View file @
5432f7a1
import
math
from
bob.io.base
import
HDF5File
from
bob.ip.color
import
rgb_to_gray
from
bob.ip.facedetect
import
(
detect_single_face
,
Sampler
,
default_cascade
,
Cascade
,
expected_eye_positions
)
bounding_box_from_annotation
,
expected_eye_positions
)
from
.
import
Base
,
bounding_box_to_annotations
class
BobIpFacedetect
(
Base
):
"""Annotator using bob.ip.facedetect"""
"""Annotator using bob.ip.facedetect
Provides topleft and bottomright annoations.
"""
def
__init__
(
self
,
cascade
=
None
,
detection_overlap
=
0.2
,
distance
=
2
,
...
...
@@ -29,7 +32,7 @@ class BobIpFacedetect(Base):
Parameters
----------
image : array
Image
gray scal
e.
Image
is Bob format RGB imag
e.
**kwargs
Ignored.
...
...
@@ -39,11 +42,21 @@ class BobIpFacedetect(Base):
The annotations in a dictionary. The keys are topleft, bottomright,
quality, leye, reye.
"""
if
image
.
ndim
!=
2
:
raise
ValueError
(
"The image must be gray scale (two dimensions)."
)
image
=
rgb_to_gray
(
image
)
bounding_box
,
quality
=
detect_single_face
(
image
,
self
.
cascade
,
self
.
sampler
,
self
.
detection_overlap
)
landmarks
=
expected_eye_positions
(
bounding_box
)
landmarks
.
update
(
bounding_box_to_annotations
(
bounding_box
))
landmarks
=
bounding_box_to_annotations
(
bounding_box
)
landmarks
[
'quality'
]
=
quality
return
landmarks
class
BoundingBoxToEyes
(
Base
):
"""Converts bounding box annotations to eye locations. The bounding box's
annotations is expected to have come from :any:`BobIpFacedetect`.
"""
def
annotate
(
self
,
image
,
annotations
,
**
kwargs
):
bbx
=
bounding_box_from_annotation
(
source
=
'direct'
,
**
annotations
)
annotations
=
dict
(
annotations
)
annotations
.
update
(
expected_eye_positions
(
bbx
))
return
annotations
bob/bio/face/annotator/bobipflandmark.py
View file @
5432f7a1
from
.
import
Base
from
bob.ip.color
import
rgb_to_gray
from
bob.ip.flandmark
import
Flandmark
...
...
@@ -16,7 +17,7 @@ class BobIpFlandmark(Base):
Parameters
----------
image : array
Image in
gray-scale
.
Image in
Bob format RGB
.
annotations : dict
The topleft and bottomright annotations are required.
**kwargs
...
...
@@ -27,11 +28,13 @@ class BobIpFlandmark(Base):
dict
Annotations with reye and leye keys or an empty dict if it fails.
"""
image
=
rgb_to_gray
(
image
)
top
,
left
=
annotations
[
'topleft'
]
top
,
left
=
max
(
top
,
0
),
max
(
left
,
0
)
top
,
left
=
int
(
max
(
top
,
0
)
)
,
int
(
max
(
left
,
0
)
)
height
=
annotations
[
'bottomright'
][
0
]
-
top
width
=
annotations
[
'bottomright'
][
1
]
-
left
height
,
width
=
min
(
height
,
image
.
shape
[
0
]),
min
(
width
,
image
.
shape
[
1
])
height
,
width
=
int
(
height
),
int
(
width
)
landmarks
=
self
.
flandmark
.
locate
(
image
,
top
,
left
,
height
,
width
)
...
...
bob/bio/face/annotator/bobipmtcnn.py
View file @
5432f7a1
...
...
@@ -11,5 +11,7 @@ class BobIpMTCNN(Base):
def
annotate
(
self
,
image
,
**
kwargs
):
bounding_box
,
landmarks
=
self
.
detector
.
detect_single_face
(
image
)
if
not
landmarks
:
return
{}
landmarks
.
update
(
bounding_box_to_annotations
(
bounding_box
))
return
landmarks
bob/bio/face/script/annotate.py
View file @
5432f7a1
...
...
@@ -3,7 +3,7 @@
import
logging
import
json
import
click
from
os.path
import
dirname
from
os.path
import
dirname
,
isfile
from
bob.extension.scripts.click_helper
import
(
verbosity_option
,
Command
,
Option
)
from
bob.io.base
import
create_directories_safe
...
...
@@ -61,20 +61,26 @@ def annotate(database, annotator, output_dir, force, jobs, **kwargs):
logger
.
debug
(
'output_dir: %s'
,
output_dir
)
logger
.
debug
(
'jobs: %s'
,
jobs
)
logger
.
debug
(
'kwargs: %s'
,
kwargs
)
biofiles
=
database
.
all_file
s
(
groups
=
None
)
biofiles
=
database
.
object
s
(
groups
=
None
,
protocol
=
database
.
protocol
)
if
jobs
>
1
:
start
,
end
=
indices
(
biofiles
,
jobs
)
biofiles
=
biofiles
[
start
:
end
]
logger
.
info
(
"Saving annotations in %s"
,
output_dir
)
total
=
len
(
biofiles
)
logger
.
info
(
"
Process
ing %d
fi
les ..."
,
total
)
logger
.
info
(
"
Annotat
ing %d
samp
les ..."
,
total
)
for
i
,
biofile
in
enumerate
(
biofiles
):
logger
.
info
(
"Extracting annotations for file %d out of %d"
,
i
+
1
,
total
)
"Extracting annotations for sample %d out of %d"
,
i
+
1
,
total
)
outpath
=
biofile
.
make_path
(
output_dir
,
'.json'
)
if
isfile
(
outpath
):
if
force
:
logger
.
debug
(
"Overwriting the annotations file `%s'"
,
outpath
)
else
:
logger
.
debug
(
"The annotation `%s' already exists"
,
outpath
)
continue
data
=
annotator
.
read_original_data
(
biofile
,
database
.
original_directory
,
database
.
original_extension
)
annot
=
annotator
(
data
,
annotations
=
database
.
annotations
(
biofile
))
outpath
=
biofile
.
make_path
(
output_dir
,
'.json'
)
create_directories_safe
(
dirname
(
outpath
))
with
open
(
outpath
,
'w'
)
as
f
:
json
.
dump
(
annot
,
f
)
json
.
dump
(
annot
,
f
,
indent
=
1
,
allow_nan
=
False
)
Write
Preview
Supports
Markdown
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