Skip to content
Snippets Groups Projects
Commit 89c683ed authored by Manuel Günther's avatar Manuel Günther
Browse files

Updated returned landmarks to be in the right order (fixes #4).

parent c39f0303
No related branches found
No related tags found
No related merge requests found
...@@ -9,7 +9,7 @@ facial landmark detector `flandmark ...@@ -9,7 +9,7 @@ facial landmark detector `flandmark
If you use this package, the author asks you to cite the following paper:: If you use this package, the author asks you to cite the following paper::
@inproceedings{Uricar-Franc-Hlavac-VISAPP-2012, @inproceedings{Uricar-Franc-Hlavac-VISAPP-2012,
author = {U{\\v{r}}i{\\v{c}}{\\'{a}}{\\v{r}}, Michal and Franc, Vojt{\\v{e}}ch and Hlav{\\'{a}}{\\v{c}}, V{\\'{a}}clav}, author = {U{\v{r}}i{\v{c}}{\'{a}}{\v{r}}, Michal and Franc, Vojt{\v{e}}ch and Hlav{\'{a}}{\v{c}}, V{\'{a}}clav},
title = {Detector of Facial Landmarks Learned by the Structured Output {SVM}}, title = {Detector of Facial Landmarks Learned by the Structured Output {SVM}},
year = {2012}, year = {2012},
pages = {547-556}, pages = {547-556},
...@@ -49,7 +49,7 @@ Installation ...@@ -49,7 +49,7 @@ Installation
You can just add a dependence for ``xbob.flandmark`` on your ``setup.py`` to You can just add a dependence for ``xbob.flandmark`` on your ``setup.py`` to
automatically download and have this package available at your satellite automatically download and have this package available at your satellite
package. This works well if Bob_ is installed centrally at your machine. package. This works well if Bob_ is installed centrally at your machine.
Otherwise, you will need to tell ``buildout`` how to build the package locally Otherwise, you will need to tell ``buildout`` how to build the package locally
and how to find Bob_. For that, just add a custom egg recipe to your and how to find Bob_. For that, just add a custom egg recipe to your
...@@ -84,7 +84,7 @@ Just type:: ...@@ -84,7 +84,7 @@ Just type::
If Bob is installed in a non-standard location, edit the file ``buildout.cfg`` If Bob is installed in a non-standard location, edit the file ``buildout.cfg``
to set the root to Bob's local installation path. Remember to use the **same to set the root to Bob's local installation path. Remember to use the **same
python interpreter** that was used to compile Bob, then execute the same steps python interpreter** that was used to compile Bob_, then execute the same steps
as above. as above.
Usage Usage
...@@ -96,7 +96,18 @@ Pretty simple, just do something like:: ...@@ -96,7 +96,18 @@ Pretty simple, just do something like::
from xbob import flandmark from xbob import flandmark
video = bob.io.VideoReader('myvideo.avi') video = bob.io.VideoReader('myvideo.avi')
localize = flandmark.Localizer() localizer = flandmark.Localizer()
for frame in video: for frame in video:
print localize(frame) print localizer(frame)
If you already have a detected bounding box, you can plug the coordinates of the bounding box into the localizer call::
landmarks = localizer(image, top, left, height, width)
In total, 8 ``landmarks`` are returned by the localizer.
For the list and the interpretation of the landmarks, please have a look `here <http://cmp.felk.cvut.cz/~uricamic/flandmark/index.php>`_.
.. warning::
Since version 1.1 of this package, the landmarks are returned in the Bob_-typical order, which is ``(y,x)``.
Please update your code to this new behavior.
...@@ -13,7 +13,7 @@ from xbob.extension import Extension, build_ext ...@@ -13,7 +13,7 @@ from xbob.extension import Extension, build_ext
setup( setup(
name="xbob.flandmark", name="xbob.flandmark",
version="1.0.11", version="1.1.0",
description="Python bindings to the flandmark keypoint localization library", description="Python bindings to the flandmark keypoint localization library",
license="GPLv3", license="GPLv3",
author='Andre Anjos', author='Andre Anjos',
......
...@@ -55,7 +55,7 @@ class Localizer { ...@@ -55,7 +55,7 @@ class Localizer {
* flandmark model. * flandmark model.
*/ */
Localizer(const std::string& opencv_cascade, Localizer(const std::string& opencv_cascade,
const std::string& flandmark_model) : const std::string& flandmark_model) :
m_cascade((CvHaarClassifierCascade*)cvLoad(opencv_cascade.c_str(), 0, 0, 0), std::ptr_fun(delete_cascade)), m_cascade((CvHaarClassifierCascade*)cvLoad(opencv_cascade.c_str(), 0, 0, 0), std::ptr_fun(delete_cascade)),
m_flandmark(flandmark_init(flandmark_model.c_str()), std::ptr_fun(delete_flandmark)), m_flandmark(flandmark_init(flandmark_model.c_str()), std::ptr_fun(delete_flandmark)),
m_storage(cvCreateMemStorage(0), std::ptr_fun(delete_storage)) m_storage(cvCreateMemStorage(0), std::ptr_fun(delete_storage))
...@@ -63,7 +63,7 @@ class Localizer { ...@@ -63,7 +63,7 @@ class Localizer {
if( !m_cascade ) { if( !m_cascade ) {
PYTHON_ERROR(RuntimeError, "Couldnt load Face detector '%s'", opencv_cascade.c_str()); PYTHON_ERROR(RuntimeError, "Couldnt load Face detector '%s'", opencv_cascade.c_str());
} }
if ( !m_flandmark ) { if ( !m_flandmark ) {
PYTHON_ERROR(RuntimeError, "Structure model wasn't created. Corrupted file '%s'", flandmark_model.c_str()); PYTHON_ERROR(RuntimeError, "Structure model wasn't created. Corrupted file '%s'", flandmark_model.c_str());
} }
...@@ -99,7 +99,7 @@ class Localizer { ...@@ -99,7 +99,7 @@ class Localizer {
for (int iface = 0; iface < (rects ? nFaces : 0); ++iface) { for (int iface = 0; iface < (rects ? nFaces : 0); ++iface) {
CvRect* r = (CvRect*)cvGetSeqElem(rects, iface); CvRect* r = (CvRect*)cvGetSeqElem(rects, iface);
dict det; dict det;
det["bbox"] = make_tuple(r->x, r->y, r->width, r->height); det["bbox"] = make_tuple(r->x, r->y, r->width, r->height);
int bbox[4] = {r->x, r->y, r->x + r->width, r->y + r->height}; int bbox[4] = {r->x, r->y, r->x + r->width, r->y + r->height};
...@@ -119,7 +119,7 @@ class Localizer { ...@@ -119,7 +119,7 @@ class Localizer {
// The first point represents the center of the bounding box used by // The first point represents the center of the bounding box used by
// the flandmark library. // the flandmark library.
for (int i = 0; i < (2*m_flandmark->data.options.M); i += 2) { for (int i = 0; i < (2*m_flandmark->data.options.M); i += 2) {
lmlist.append(make_tuple(m_landmarks[i], m_landmarks[i+1])); lmlist.append(make_tuple(m_landmarks[i+1], m_landmarks[i]));
} }
} }
det["landmark"] = tuple(lmlist); det["landmark"] = tuple(lmlist);
...@@ -153,12 +153,12 @@ class Localizer { ...@@ -153,12 +153,12 @@ class Localizer {
flandmark_result = flandmark_detect(ipl_image.get(), bbox, m_flandmark.get(), flandmark_result = flandmark_detect(ipl_image.get(), bbox, m_flandmark.get(),
m_landmarks.get()); m_landmarks.get());
} }
list lmlist; ///< landmark list list lmlist; ///< landmark list
if (flandmark_result == NO_ERR) { if (flandmark_result == NO_ERR) {
for (int i = 0; i < (2*m_flandmark->data.options.M); i += 2) { for (int i = 0; i < (2*m_flandmark->data.options.M); i += 2) {
lmlist.append(make_tuple(m_landmarks[i], m_landmarks[i+1])); lmlist.append(make_tuple(m_landmarks[i+1], m_landmarks[i]));
} }
} }
......
#!/usr/bin/env python #!/usr/bin/env python
# vim: set fileencoding=utf-8 : # vim: set fileencoding=utf-8 :
# Andre Anjos <andre.anjos@idiap.ch> # Andre Anjos <andre.anjos@idiap.ch>
# Fri 21 Sep 2012 10:43:12 CEST # Fri 21 Sep 2012 10:43:12 CEST
"""Annotates videos, dumps annotations as text files. """Annotates videos, dumps annotations as text files.
...@@ -114,7 +114,7 @@ def main(): ...@@ -114,7 +114,7 @@ def main():
bbox = biggest['bbox'] bbox = biggest['bbox']
landmarks = biggest['landmark'] landmarks = biggest['landmark']
output.write("%d %d %d %d %d " % ((k,) + bbox)) output.write("%d %d %d %d %d " % ((k,) + bbox))
lstr = " ".join("%d %d" % (round(p[0]), round(p[1])) for p in landmarks) lstr = " ".join("%d %d" % (round(p[1]), round(p[0])) for p in landmarks)
output.write(lstr + "\n") output.write(lstr + "\n")
if args.verbose and args.output is not None: if args.verbose and args.output is not None:
sys.stdout.write('.') sys.stdout.write('.')
...@@ -125,7 +125,7 @@ def main(): ...@@ -125,7 +125,7 @@ def main():
if args.verbose and args.output is not None: if args.verbose and args.output is not None:
sys.stdout.write('x') sys.stdout.write('x')
sys.stdout.flush() sys.stdout.flush()
if args.verbose and args.output is not None: if args.verbose and args.output is not None:
sys.stdout.write('\n') sys.stdout.write('\n')
sys.stdout.flush() sys.stdout.flush()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment