Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
bob.db.fargo
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
bob
bob.db.fargo
Commits
b0e78cef
Commit
b0e78cef
authored
8 years ago
by
Guillaume HEUSCH
Browse files
Options
Downloads
Patches
Plain Diff
[extract eyes] made scripts to extract eyes center from detected landmarks
parent
3fce204b
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bob/db/fargo/scripts/eyes_center_from_landmarks.py
+408
-0
408 additions, 0 deletions
bob/db/fargo/scripts/eyes_center_from_landmarks.py
setup.py
+1
-0
1 addition, 0 deletions
setup.py
with
409 additions
and
0 deletions
bob/db/fargo/scripts/eyes_center_from_landmarks.py
0 → 100644
+
408
−
0
View file @
b0e78cef
#!/usr/bin/env python
# encoding: utf-8
# Guillaume HEUSCH <guillaume.heusch@idiap.ch>
# Mon 21 Nov 08:25:54 CET 2016
"""
Eyes center extractor for the FARGO images (%(version)s)
Usage:
%(prog)s [--ldmdir=<path>] [--eyesdir=<path>] [--imagesdir=<path>]
[--verbose ...] [--plot] [--log=<string>]
Options:
-h, --help Show this screen.
-V, --version Show version.
-l, --ldmdir=<path> The path to the landmarks on your disk.
-e, --eyesdir=<path> Where to store saved images.
-i, --imagesdir=<path> Where the images are stored.
--log=<string> Log filename [default: logs.txt]
-v, --verbose Increase the verbosity (may appear multiple times).
-P, --plot Show some stuff
Example:
To get the eyes center, do
$ %(prog)s --ldmdir path/to/database
See
'
%(prog)s --help
'
for more information.
"""
import
os
import
sys
import
pkg_resources
import
logging
__logging_format__
=
'
[%(levelname)s] %(message)s
'
logging
.
basicConfig
(
format
=
__logging_format__
)
logger
=
logging
.
getLogger
(
"
extract_log
"
)
from
docopt
import
docopt
version
=
pkg_resources
.
require
(
'
bob.db.fargo
'
)[
0
].
version
import
numpy
import
bob.io.base
import
bob.io.image
import
bob.ip.draw
def
get_frame
(
image_dir
,
index
):
"""
get_frame(image_dir, index) -> frame
This function gets the frame that corresponds to the landmarks.
**Parameters**
``image_dir`` (path):
The dir continaing the image
``index`` (int):
The index of the image
**Returns**
``frame`` (numpy array):
The frame where the annotation have been made
"""
image_file
=
os
.
path
.
join
(
image_dir
,
'
{:0>2d}.png
'
.
format
(
index
))
if
os
.
path
.
isfile
(
image_file
):
frame
=
bob
.
io
.
base
.
load
(
image_file
)
return
frame
def
is_annotation_complete
(
landmarks
):
"""
is_annotation_complete(landmarks) -> True or False
This function checks if the landmarks read from the provided
file contain what we need to infer eyes center (i.e. eyes corner)
**Parameters**
``landmarks`` (dict):
The landmarks, read from a txt file and stored as a dict
**Returns**
``bool`` (boolean):
True if all eyes corners are present, False otherwise.
"""
if
'
1
'
not
in
landmarks
.
keys
()
or
'
2
'
not
in
landmarks
.
keys
()
or
'
3
'
not
in
landmarks
.
keys
()
or
'
4
'
not
in
landmarks
.
keys
():
return
False
return
True
def
get_eyes_center
(
landmarks
):
"""
get_eyes_center(landmarks) -> eyes_center
This function computes the position of the eyes center,
based on eyes corners.
Note that left and right are defined wrt the imaged subject.
**Parameters**
``landmarks`` (dict):
The landmarks, read from a txt file and stored as a dict
**Returns**
``eyes_center`` (tuple):
Tuple containing the (x, y) position of the right and left eye.
"""
reye_x
=
int
(
0.5
*
(
landmarks
[
'
1
'
][
1
]
+
landmarks
[
'
2
'
][
1
]))
reye_y
=
int
(
0.5
*
(
landmarks
[
'
1
'
][
0
]
+
landmarks
[
'
2
'
][
0
]))
leye_x
=
int
(
0.5
*
(
landmarks
[
'
3
'
][
1
]
+
landmarks
[
'
4
'
][
1
]))
leye_y
=
int
(
0.5
*
(
landmarks
[
'
3
'
][
0
]
+
landmarks
[
'
4
'
][
0
]))
return
(
reye_x
,
reye_y
,
leye_x
,
leye_y
)
def
draw_eyes_center
(
frame
,
positions
):
"""
draw_eyes_center(frame, positions) -> frame
This function draws the computed eyes center on the provided image.
**Parameters**
``frame`` (numpy array):
The frame on which to draw eyes center.
``positions`` (tuple):
The position of the center of both eyes.
"""
reye_x
=
positions
[
0
]
reye_y
=
positions
[
1
]
leye_x
=
positions
[
2
]
leye_y
=
positions
[
3
]
if
frame
.
shape
[
0
]
==
3
:
bob
.
ip
.
draw
.
cross
(
frame
,
(
reye_y
,
reye_x
),
4
,
(
255
,
0
,
0
))
bob
.
ip
.
draw
.
cross
(
frame
,
(
leye_y
,
leye_x
),
4
,
(
255
,
0
,
0
))
else
:
bob
.
ip
.
draw
.
cross
(
frame
,
(
reye_y
,
reye_x
),
4
,
(
255
))
bob
.
ip
.
draw
.
cross
(
frame
,
(
leye_y
,
leye_x
),
4
,
(
255
))
return
frame
def
draw_landmarks
(
frame
,
landmarks
):
"""
draw_landmarks(frame, landmarks) -> frame
This function draws both the original landmarks (provided in the file)
and the projected ones.
**Parameters**
``frame`` (numpy array):
The frame on which to draw eyes center.
``landmarks`` (dict):
The landmarks
"""
for
i
in
landmarks
.
keys
():
if
frame
.
shape
[
0
]
==
3
:
bob
.
ip
.
draw
.
plus
(
frame
,
(
landmarks
[
i
][
0
],
landmarks
[
i
][
1
]),
4
,
(
0
,
255
,
0
))
else
:
bob
.
ip
.
draw
.
plus
(
frame
,
(
landmarks
[
i
][
0
],
landmarks
[
i
][
1
]),
4
,
(
255
))
return
frame
def
get_landmarks
(
annotation_file
):
"""
get_landmarks(annotation_file) -> landmarks
This function reads landmarks from a file and load
them into a dictionary.
Note: left and right are defined in terms of subject
Landmarks:
1 right corner of right eye
2 left corner of right eye
3 right corner of left eye
4 left corner of left eye
5
6
7
8
9
10
11
12
13
14
15
16
**Parameters**
``annotated_file`` (path):
The path to the file containing the landmarks.
**Returns**
``landmarks`` (dict):
The landmarks.
"""
with
open
(
annotation_file
,
"
r
"
)
as
c
:
landmarks
=
{}
for
line
in
c
:
line
=
line
.
rstrip
()
ints
=
line
.
split
()
landmarks
[
ints
[
0
]]
=
((
int
(
ints
[
2
]),
int
(
ints
[
1
])))
return
landmarks
def
write_eyes_pos
(
eyes
,
eyes_dir
):
"""
write_eyes_pos(eyes, eyes_dir)
This function write the eyes center in text file(s).
**Parameters**
``eyes`` (tuple):
tuple containing the (x,y) coordinates of the eyes center.
``eyes_dir`` (path):
The path to the dir where the file(s) are written.
"""
if
not
os
.
path
.
isdir
(
eyes_dir
):
os
.
makedirs
(
eyes_dir
)
for
i
in
range
(
0
,
10
):
eyes_filename
=
os
.
path
.
join
(
eyes_dir
,
'
{:0>2d}.pos
'
.
format
(
i
))
eyes_file
=
open
(
eyes_filename
,
'
w
'
)
eyes_file
.
write
(
'
{0} {1} {2} {3}
'
.
format
(
eyes
[
0
],
eyes
[
1
],
eyes
[
2
],
eyes
[
3
]))
eyes_file
.
close
()
def
annotations_exist
(
annotation_dir
):
"""
annotations_exist(annotation_dir) -> [True, False]
This function checks if the annotation (i.e. eyes center) already exists
**Parameters**
``annotation_dir`` (path):
The directory where the annotations should be saved.
**Returns**
``bool`` (boolean):
True if all annotations exist, False otherwise.
"""
for
i
in
range
(
0
,
10
):
annotation_file
=
os
.
path
.
join
(
annotation_dir
,
'
{:0>2d}.pos
'
.
format
(
i
))
if
not
os
.
path
.
isfile
(
annotation_file
):
return
False
return
True
def
main
(
user_input
=
None
):
"""
Main function to extract eyes center from existing annotations.
"""
# Parse the command-line arguments
if
user_input
is
not
None
:
arguments
=
user_input
else
:
arguments
=
sys
.
argv
[
1
:]
prog
=
os
.
path
.
basename
(
sys
.
argv
[
0
])
completions
=
dict
(
prog
=
prog
,
version
=
version
,)
args
=
docopt
(
__doc__
%
completions
,
argv
=
arguments
,
version
=
'
Eyes position extractor (%s)
'
%
version
,)
# if the user wants more verbosity, lowers the logging level
if
args
[
'
--verbose
'
]
==
1
:
logging
.
getLogger
(
"
extract_log
"
).
setLevel
(
logging
.
INFO
)
elif
args
[
'
--verbose
'
]
>=
2
:
logging
.
getLogger
(
"
extract_log
"
).
setLevel
(
logging
.
DEBUG
)
if
args
[
'
--ldmdir
'
]
is
None
:
logger
.
warning
(
"
You should provide a valid path to the landmarks
"
)
sys
.
exit
()
base_dir
=
args
[
'
--ldmdir
'
]
if
not
os
.
path
.
isdir
(
args
[
'
--eyesdir
'
]):
os
.
mkdir
(
args
[
'
--eyesdir
'
])
logfile
=
open
(
args
[
'
--log
'
],
'
w
'
)
# to compute various stats
total_counter
=
0
inexisting_counter
=
0
incomplete_counter
=
0
projection_counter
=
0
heuristic_counter
=
0
# go through the subjects
for
subject
in
os
.
listdir
(
base_dir
):
sessions
=
[
'
controlled
'
,
'
dark
'
,
'
outdoor
'
]
# small hack to process FdV subjects ...
if
int
(
subject
)
>=
129
:
sessions
=
[
'
fdv
'
]
for
session
in
sessions
:
session_dir
=
os
.
path
.
abspath
(
os
.
path
.
join
(
base_dir
,
subject
,
session
))
for
condition
in
[
'
SR300-laptop
'
,
'
SR300-mobile
'
]:
for
recording
in
[
'
0
'
,
'
1
'
]:
logger
.
debug
(
"
===== Subject {0}, session {1}, device {2}, recording {3} ...
"
.
format
(
subject
,
session
,
condition
,
recording
))
# create directories to save the extracted annotations
if
not
os
.
path
.
isdir
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
)):
os
.
makedirs
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
))
if
not
os
.
path
.
isdir
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
color
'
)):
os
.
makedirs
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
color
'
))
if
not
os
.
path
.
isdir
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
ir
'
)):
os
.
makedirs
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
ir
'
))
if
not
os
.
path
.
isdir
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
depth
'
)):
os
.
makedirs
(
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
depth
'
))
# the directories - input
recording_dir
=
os
.
path
.
join
(
session_dir
,
condition
,
recording
)
color_dir
=
os
.
path
.
join
(
recording_dir
,
'
color
'
)
ir_dir
=
os
.
path
.
join
(
recording_dir
,
'
ir
'
)
# the directories - output
color_eyes_dir
=
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
color
'
)
ir_eyes_dir
=
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
ir
'
)
depth_eyes_dir
=
os
.
path
.
join
(
args
[
'
--eyesdir
'
],
subject
,
session
,
condition
,
recording
,
'
depth
'
)
# check if annotations for this recording already exists
if
annotations_exist
(
color_eyes_dir
)
and
annotations_exist
(
ir_eyes_dir
)
and
annotations_exist
(
depth_eyes_dir
):
logger
.
warn
(
'
Existing annotations for {0}
'
.
format
(
recording_dir
))
continue
# loop on the images extracted from this sequences
for
i
in
range
(
0
,
10
):
# read the original landmarks - color
color_ldm_file
=
os
.
path
.
join
(
color_dir
,
'
{:0>2d}.pos
'
.
format
(
i
))
try
:
color_landmarks
=
get_landmarks
(
color_ldm_file
)
except
IOError
:
logger
.
warn
(
"
No color annotations for recording {0}
"
.
format
(
recording_dir
))
logfile
.
write
(
'
[NO ANNOTATIONS]
'
+
color_dir
+
'
\n
'
)
inexisting_counter
+=
1
# read the original landmarks - ir
ir_ldm_file
=
os
.
path
.
join
(
ir_dir
,
'
{:0>2d}.pos
'
.
format
(
i
))
try
:
ir_landmarks
=
get_landmarks
(
ir_ldm_file
)
except
IOError
:
logger
.
warn
(
"
No ir annotations for recording {0}
"
.
format
(
recording_dir
))
logfile
.
write
(
'
[NO ANNOTATIONS]
'
+
ir_dir
+
'
\n
'
)
inexisting_counter
+=
1
# check if we have all we need (possibly after re-projection)
if
is_annotation_complete
(
color_landmarks
)
and
is_annotation_complete
(
ir_landmarks
):
# get the eyes center
color_eyes
=
get_eyes_center
(
color_landmarks
)
ir_eyes
=
get_eyes_center
(
ir_landmarks
)
# and save the file(s) - note that ir and depth are the same
write_eyes_pos
(
color_eyes
,
color_eyes_dir
)
write_eyes_pos
(
ir_eyes
,
ir_eyes_dir
)
write_eyes_pos
(
ir_eyes
,
depth_eyes_dir
)
# plot stuff if asked for
if
bool
(
args
[
'
--plot
'
]):
if
args
[
'
--imagesdir
'
]
is
None
:
logger
.
warn
(
"
You should provide an image directory if you want to plot something ...
"
)
else
:
color_frame_dir
=
os
.
path
.
join
(
args
[
'
--imagesdir
'
],
subject
,
session
,
condition
,
recording
,
'
color
'
)
color_frame
=
get_frame
(
color_frame_dir
,
i
)
display_color
=
draw_eyes_center
(
color_frame
,
color_eyes
)
ir_frame_dir
=
os
.
path
.
join
(
args
[
'
--imagesdir
'
],
subject
,
session
,
condition
,
recording
,
'
ir
'
)
ir_frame
=
get_frame
(
ir_frame_dir
,
i
)
display_ir
=
draw_eyes_center
(
ir_frame
,
ir_eyes
)
from
matplotlib
import
pyplot
f
,
axarr
=
pyplot
.
subplots
(
1
,
2
)
pyplot
.
suptitle
(
'
Inferred eyes center
'
)
axarr
[
0
].
imshow
(
numpy
.
rollaxis
(
numpy
.
rollaxis
(
display_color
,
2
),
2
))
axarr
[
0
].
set_title
(
"
Color
"
)
axarr
[
1
].
imshow
(
display_ir
,
cmap
=
'
gray
'
)
axarr
[
1
].
set_title
(
"
NIR
"
)
pyplot
.
show
()
if
args
[
'
--verbose
'
]
>=
2
:
display_color
=
draw_landmarks
(
color_frame
,
color_landmarks
)
display_ir
=
draw_landmarks
(
ir_frame
,
ir_landmarks
)
f
,
axarr
=
pyplot
.
subplots
(
1
,
2
)
pyplot
.
suptitle
(
'
Landmarks
'
)
axarr
[
0
].
imshow
(
numpy
.
rollaxis
(
numpy
.
rollaxis
(
display_color
,
2
),
2
))
axarr
[
0
].
set_title
(
"
Color
"
)
axarr
[
1
].
imshow
(
display_ir
,
cmap
=
'
gray
'
)
axarr
[
1
].
set_title
(
"
NIR
"
)
pyplot
.
show
()
total_counter
+=
1
logger
.
info
(
"
Processed {0} sequences
"
.
format
(
total_counter
))
logger
.
info
(
"
\t
{0} had no annotations
"
.
format
(
inexisting_counter
))
logger
.
info
(
"
\t
{0} needed reprojection
"
.
format
(
projection_counter
))
logger
.
info
(
"
\t
{0} where incomplete
"
.
format
(
incomplete_counter
))
logger
.
info
(
"
\t
{0} needed heuristic (incomplete after reprojection)
"
.
format
(
heuristic_counter
))
logfile
.
close
()
This diff is collapsed.
Click to expand it.
setup.py
+
1
−
0
View file @
b0e78cef
...
...
@@ -38,6 +38,7 @@ setup(
'
make_public_lists.py = bob.db.fargo.scripts.make_public_lists:main
'
,
'
make_pose_lists.py = bob.db.fargo.scripts.make_pose_lists:main
'
,
'
extract_eyes_center.py = bob.db.fargo.scripts.extract_eyes_center:main
'
,
'
eyes_center_from_landmarks.py = bob.db.fargo.scripts.eyes_center_from_landmarks:main
'
,
'
convert_ir_and_depth.py = bob.db.fargo.scripts.convert_ir_and_depth:main
'
,
'
reencode_color.py = bob.db.fargo.scripts.reencode_color:main
'
,
'
detect_faces_fargo.py = bob.db.fargo.scripts.detect_faces_fargo:main
'
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment