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.ip.skincolorfilter
Commits
ac8035f9
Commit
ac8035f9
authored
Apr 06, 2016
by
Guillaume HEUSCH
Browse files
[doc] changed the test image, reformat the docstrings
parent
6cd0955d
Changes
5
Hide whitespace changes
Inline
Side-by-side
bob/ip/skincolorfilter/script/test.py
0 → 100644
View file @
ac8035f9
#!/usr/bin/env python
# encoding: utf-8
# Guillaume HEUSCH <guillaume.heusch@idiap.ch>
# Tue 5 Apr 11:20:29 CEST 2016
"""Test Units
"""
import
nose.tools
import
numpy
import
bob.ip.skincolorfilter
as
scf
skin_filter
=
scf
.
SkinColorFilter
()
def
test_circular_mask
():
"""
Test the generation of the circular mask
"""
# limit case: the center of the image is located at (0,0)
# so it's considered as inside (x**2 + y**2) = 0 < 0.4
image
=
numpy
.
zeros
((
3
,
1
,
1
))
skin_filter
.
generate_circular_mask
(
image
)
assert
numpy
.
all
(
skin_filter
.
circular_mask
),
"a 1x1 image should be True"
# easy case - the "cross" should be true
image
=
numpy
.
zeros
((
3
,
3
,
3
))
skin_filter
.
generate_circular_mask
(
image
)
assert
skin_filter
.
circular_mask
[
0
,
1
],
"middle-top should be inside"
assert
numpy
.
all
(
skin_filter
.
circular_mask
[
1
,
:]),
"the whole middle line should be inside"
assert
skin_filter
.
circular_mask
[
2
,
1
],
"middle-bottom should be inside"
# more realistic case - radius will be 0.4*15=6 pixels
image
=
numpy
.
zeros
((
3
,
15
,
15
))
skin_filter
.
generate_circular_mask
(
image
)
print
skin_filter
.
circular_mask
# left
assert
not
(
skin_filter
.
circular_mask
[
7
,
1
]),
"(7,1) should not be inside"
assert
skin_filter
.
circular_mask
[
7
,
2
],
"(7,2) should be inside"
# top
assert
not
(
skin_filter
.
circular_mask
[
1
,
7
]),
"(1,7) should not be inside"
assert
skin_filter
.
circular_mask
[
2
,
7
],
"(2,7) should be inside"
# right
assert
not
(
skin_filter
.
circular_mask
[
7
,
13
]),
"(7,13) should not be inside"
assert
skin_filter
.
circular_mask
[
7
,
12
],
"(7,12) should be inside"
# bottom
assert
not
(
skin_filter
.
circular_mask
[
13
,
7
]),
"(13, 7) should not be inside"
assert
skin_filter
.
circular_mask
[
12
,
7
],
"(12, 7) should be inside"
def
test_luma_mask
():
"""
Test the generation of the luma mask
"""
# generate a greyish image
image
=
numpy
.
ones
((
3
,
11
,
11
))
*
(
numpy
.
random
.
standard_normal
((
3
,
11
,
11
))
+
128
)
image
[:,
0
,
:]
=
0
# first line is black
image
[:,
-
1
,
:]
=
255
# last line is white
# the circular mask (to compute mean and std luma)
skin_filter
.
generate_circular_mask
(
image
)
skin_filter
.
remove_luma
(
image
)
# the first and last line should be all False - extreme values
assert
not
(
numpy
.
all
(
skin_filter
.
luma_mask
[:,
0
]))
assert
not
(
numpy
.
all
(
skin_filter
.
luma_mask
[:,
-
1
]))
# there should be at least one True everywhere else
assert
numpy
.
any
(
skin_filter
.
luma_mask
)
def
test_estimate_parameters
():
"""
Test the ML estimation of the Gaussian parameters
"""
# a red image
image
=
numpy
.
zeros
((
3
,
11
,
11
))
image
[
0
,
:,
:]
=
255
skin_filter
.
get_gaussian_parameters
(
image
)
assert
(
skin_filter
.
mean
==
[
1.0
,
0.0
]).
all
(),
"mean for a red image is not OK"
assert
(
skin_filter
.
covariance
==
[[
0.0
,
0.0
],
[
0.0
,
0.0
]]).
all
(),
"covariance for red image is not OK"
# a green image
image
=
numpy
.
zeros
((
3
,
11
,
11
))
image
[
1
,
:,
:]
=
255
skin_filter
.
get_gaussian_parameters
(
image
)
assert
(
skin_filter
.
mean
==
[
0.0
,
1.0
]).
all
(),
"mean for a green image is not OK"
assert
(
skin_filter
.
covariance
==
[[
0.0
,
0.0
],
[
0.0
,
0.0
]]).
all
(),
"covariance for green image is not OK"
doc/conf.py
View file @
ac8035f9
...
...
@@ -245,7 +245,8 @@ autodoc_default_flags = ['members', 'undoc-members', 'inherited-members', 'show-
# For inter-documentation mapping:
from
bob.extension.utils
import
link_documentation
intersphinx_mapping
=
link_documentation
([
'python'
,
'numpy'
,
'scipy'
,
'matplotlib'
,
'bob.db.verification.utils'
])
#intersphinx_mapping = link_documentation(['python', 'numpy', 'scipy', 'matplotlib', 'bob.db.verification.utils'])
intersphinx_mapping
=
link_documentation
([
'bob.ip.facedetect'
])
def
setup
(
app
):
...
...
doc/guide.rst
View file @
ac8035f9
...
...
@@ -7,18 +7,23 @@
import bob.io.base.test_utils
import bob.io.image
import bob.ip.facedetect
from
bob.ip.skincolorfilter
.skin_color_filter import SkinColorFilter
import
bob.ip.skincolorfilter
import pkg_resources
face_image = bob.io.base.load(bob.io.base.test_utils.datafile('
001.pn
g', 'bob.ip.skincolorfilter'))
face_image = bob.io.base.load(bob.io.base.test_utils.datafile('
test-face.jp
g', 'bob.ip.skincolorfilter'))
=============
User
s
Guide
User Guide
=============
This skin color filter relies on the result of face detection. The skin color values
are estimated from the center of the detected face area. The probability of a pixel
to be of skin color is modeled as a bivariate gaussian in the normalized rg colorspace
This skin color filter relies on the result of face detection, hence you might want to
use :py:mod:`bob.ip.facedetect` (and in particular :py:func:`bob.ip.facedetect.detect_single_face`)
to first detect a face in the image.
The skin color distribution is modeled as a bivariate gaussian in the normalised rg colorspace.
The parameters of the distribution are estimated from a circular region centered on the face,
where extreme luma values have been eliminated (see [taylor-spie-2014]_ for details).
Skin pixels detection in a single image
---------------------------------------
...
...
@@ -29,21 +34,22 @@ Hence, to detect skin pixels inside a face image, you should do the following:
.. doctest::
>>> face_image = bob.io.base.load('
001.pn
g') # doctest: +SKIP
>>> face_image = bob.io.base.load('
test-face.jp
g') # doctest: +SKIP
>>> detection = bob.ip.facedetect.detect_single_face(face_image)
>>> bounding_box, quality = bob.ip.facedetect.detect_single_face(face_image)
>>> face = face_image[:, bounding_box.top:bounding_box.bottom, bounding_box.left:bounding_box.right]
>>> skin_filter = SkinColorFilter()
>>> skin_filter.
get
_gaussian_parameters(face)
>>> skin_mask = skin_filter.get_skin_
pixels
(face_image, 0.5)
>>> skin_filter =
bob.ip.skincolorfilter.
SkinColorFilter()
>>> skin_filter.
estimate
_gaussian_parameters(face)
>>> skin_mask = skin_filter.get_skin_
mask
(face_image, 0.5)
.. plot:: plot/detect_skin_pixels.py
:include-source: False
Picture taken from https://stocksnap.io/photo/W7GS1022QN
Skin pixels detection in videos
-------------------------------
To detect skin pixels in video, you do
n'
t need to re-
init
the gaussian parameters at each frame.
However, you can do it
if you really want to by calling the appropriate function (i.e. get
_gaussian_parameters
)
.
To detect skin pixels in video, you do
no
t need to re-
estimate
the gaussian parameters at each frame.
However, you can do it
by calling :py:meth:`SkinColorFilter.estimate
_gaussian_parameters
`
.
doc/plot/detect_skin_pixels.py
View file @
ac8035f9
...
...
@@ -5,25 +5,27 @@ import bob.io.base
import
bob.io.base.test_utils
import
bob.io.image
import
bob.ip.facedetect
from
bob.ip.skincolorfilter
.skin_color_filter
import
SkinColorFilter
from
bob.ip.skincolorfilter
import
SkinColorFilter
face_image
=
bob
.
io
.
base
.
load
(
bob
.
io
.
base
.
test_utils
.
datafile
(
'
001.pn
g'
,
'bob.ip.skincolorfilter'
))
face_image
=
bob
.
io
.
base
.
load
(
bob
.
io
.
base
.
test_utils
.
datafile
(
'
test-face.jp
g'
,
'bob.ip.skincolorfilter'
))
detection
=
bob
.
ip
.
facedetect
.
detect_single_face
(
face_image
)
bounding_box
,
quality
=
bob
.
ip
.
facedetect
.
detect_single_face
(
face_image
)
face
=
face_image
[:,
bounding_box
.
top
:
bounding_box
.
bottom
,
bounding_box
.
left
:
bounding_box
.
right
]
skin_filter
=
SkinColorFilter
()
skin_filter
.
get
_gaussian_parameters
(
face
)
skin_mask
=
skin_filter
.
get_skin_
pixels
(
face_image
,
0.5
)
skin_filter
.
estimate
_gaussian_parameters
(
face
)
skin_mask
=
skin_filter
.
get_skin_
mask
(
face_image
,
0.5
)
skin_image
=
numpy
.
copy
(
face_image
)
skin_image
[:,
numpy
.
logical_not
(
skin_mask
)]
=
0
from
matplotlib
import
pyplot
f
,
ax
=
pyplot
.
subplots
(
2
,
1
)
ax
[
0
].
set_title
(
'Original Image'
)
ax
[
0
].
set_xticks
([])
ax
[
0
].
set_yticks
([])
ax
[
0
].
imshow
(
numpy
.
rollaxis
(
numpy
.
rollaxis
(
face_image
,
2
),
2
))
ax
[
1
].
set_title
(
'Detected skin pixels'
)
ax
[
1
].
set_xticks
([])
ax
[
1
].
set_yticks
([])
ax
[
1
].
imshow
(
numpy
.
rollaxis
(
numpy
.
rollaxis
(
skin_image
,
2
),
2
))
f
,
ax
=
pyplot
.
subplots
(
1
,
1
)
ax
.
set_title
(
'Original Image'
)
ax
.
set_xticks
([])
ax
.
set_yticks
([])
ax
.
imshow
(
numpy
.
rollaxis
(
numpy
.
rollaxis
(
face_image
,
2
),
2
))
f
,
ax
=
pyplot
.
subplots
(
1
,
1
)
ax
.
set_title
(
'Detected skin pixels'
)
ax
.
set_xticks
([])
ax
.
set_yticks
([])
ax
.
imshow
(
numpy
.
rollaxis
(
numpy
.
rollaxis
(
skin_image
,
2
),
2
))
doc/py_api.rst
View file @
ac8035f9
...
...
@@ -2,5 +2,5 @@
Python API
============
.. automodule:: bob.ip.skincolorfilter
.skin_color_filter
.. automodule:: bob.ip.skincolorfilter
:members:
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