Hello,
I have a problem using shape_predictor for face landmarks detection using python 2.7 in anaconda.
I compiled dlib and verified boost lib path according to these issues:
I also tried to rebuild Boost from source, but still having the same error:
Traceback (most recent call last):
File "face_landmark_detection.py", line 66, in <module>
predictor = dlib.shape_predictor(predictor_path)
Boost.Python.ArgumentError: Python argument types in
shape_predictor.__init__(shape_predictor, str)
did not match C++ signature:
__init__(boost::python::api::object, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
__init__(_object*)
Boost must be compiled against the version of python you are using, the one in anaconda. It's probably being compiled against a version of python installed by your OS instead, leading to this error.
In any case, this happens because you aren't using the same python version while compiling boost and running the compiled output.
Hello: I just faced this issue; see also
I hope the following is helpful, to others. :-)
SOLUTION -- GETTING DLIB FACIAL LANDMARKS SCRIPT TO RUN IN P3!
==============================================================
[2016-Oct-25]
PROBLEM:
--------
I was getting these errors when running some (not all) Dlib facial landmarks-related
Python scripts in my Python 3.5 virtual environment (p3 venv):
Traceback (most recent call last):
File "face_landmark_detection.py", line 66, in
predictor = dlib.shape_predictor(predictor_path)
Boost.Python.ArgumentError: Python argument types in
shape_predictor.__init__(shape_predictor, str)
did not match C++ signature:
__init__(boost::python::api::object, std::__cxx11::basic_string, std::allocator >)
__init__(_object*)
I Googled and tried everything I could think of to solve this. Here is my solution
(your mileage may vary).
----------------------------------------
1. HOST ENVIRONMENT
----------------------------------------
To troubleshoot/resolve this issue, in my host (Arch Linux x86_64 on Intel i7-4790
CPU-based system; Python 3.5), non-virtual environment, I have { boost | dlib }
"pre-installed."
[Aside: the "boost: install was already present prior to this issue; earlier today I
installed -- from source -- dlib in my host environment, to finally get my scripts
working. I then went ahead with the summary posted here, to get those scripts
running in my Python virtual environment.]
boost:
------
whereis boost
boost: /usr/include/boost ## installed via: sudo pacman -S boost
dlib (installed from source):
-----------------------------
# compile dlib c++ example programs:
# ----------------------------------
cd /mnt/Vancouver/apps
git clone https://github.com/davisking/dlib
cd /mnt/Vancouver/apps/dlib
mkdir build
cd build
cmake ..
cmake --build . --config Release
# compile dlib python api:
# --------------------------
cd ..
pwd ## /mnt/Vancouver/apps/dlib
python setup.py install
# python setup.py install --yes USE_AVX_INSTRUCTIONS
# use the line above instead, if your Intel CPU supports AVX, per:
# https://github.com/davisking/dlib
# https://pypi.python.org/pypi/dlib
----------------------------------------
2. PYTHON 3.5 VIRTUAL ENVIRONMENT
----------------------------------------
source activate py35 ## activate Anaconda Python 3.5 venv
Then, in p3 venv, searched,
pip list | egrep -i 'pkg1|pkg2|...'
conda list | egrep -i 'pkg1|pkg2|...'
... for all pip- and conda-installed
{ scikit-learn | scikit-image | scipy | boost | boost-python }
... versions, and removed these, if present:
pip list | egrep -i 'scikit|scipy|boost'
conda list | egrep -i 'scikit|scipy|boost'
... via
pip uninstall pkg_name
conda uninstall pkg_name
Oddly, even though I reset my terminal ("exec bash"), I needed to QUIT the terminal and
open a new one (as even thought there was no apparent trace of dlib (pip list; conda list)
in my p3 venv, I could still launch Python and import dlib). :-/ Easy "fix."
Finally, in that (new) p3 venv session, I installed (note use of "pip install", even though
I am in a conda venv):
pip install dlib
pip install scikit-image
pip install scikit-learn
pip install scipy
After doing that, my dlib "find facial landmarks"" Python scripts successfully executed in my
p3 venv, as they also did in my host env:
python finding-face-landmarks.py files/carm_victoria_july_13_2012.jpg
... ## exit code 0 :-)
python face_landmark_detection.py ../files/shape_predictor_68_face_landmarks.dat \
files/carm_victoria_july_13_2012.jpg
... ## exit code 0 :-)
Scripts mentioned (above):
--------------------------
face_landmark_detection.py :
http://dlib.net/face_landmark_detection.py.html
# see comments in that code for face landmarks .DAT file source location
finding-face-landmarks.py :
https://gist.github.com/ageitgey/ae340db3e493530d5e1f9c15292e5c74
... via:
https://medium.com/@ageitgey/machine-learning-is-fun-part-4-modern-face-recognition-with-deep-learning-c3cffc121d78
Q.E.D. (Whew!)
Yeah, boost.python has an awful build process. I'll switch to pybind11 instead of boost.python at some point in the future (https://github.com/davisking/dlib/issues/293). That should make building the python extensions pretty trivial.
Hi @davisking,
I'm still a bit lost on debugging this issue. Could you indicate how we can identify where boost is installed, and potentially force recompiling/using the one installed through conda to make it compatible with dlib (on linux)? Thanks!
There are no standards at all for boost and python packagers. Practically everyone who posts in the dlib forums has their computer configured in some different way, with boost in some random different folder, or multiple copies compiled against multiple different and incompatible versions of python they have strewn throughout their filesystem.
The entire Python build system (or lack of a build system really) is just a total clusterfuck. So no, there is no general solution other than you should know what software you install on your computer and try and be consistent about what you install.
Also, I realize that's frustrating. The best advice I can give is to compile boost yourself. That way at least you know the copy of boost in the folder you are looking at is compiled against the version of python you are using.
Thanks @davisking for the quick response.
I have tried installing boost through
sudo apt-get install libboost-all-devconda install boost andboot/bootstrap.sh; sudo ./b2 --with=all -j $n installNone of these installs generated errors, but dlib (after re-installing it every time with python setup.py install) continues throwing Boost.Python.ArgumentError: Python argument types in
shape_predictor.__init__(shape_predictor, str)
I also tried to remove Ubuntu's python2.7 to ensure that boost would link to anaconda's python, again without success.
I'm not familiar with this kind of issue and boost's documentation is pretty rough. Would you have some hints on how to proceed from here? i.e. perhaps locate an already existing boost ? selecting a specific compiler? check the order of compilation and installation steps?
You have to figure out how to compile boost against the version of python you are using. Like I was saying, I don't know how to do that for all python configurations. But this isn't a dlib problem. Fundamentally, it's happening because you are compiling boost against one copy of python and then running another version of python (the one in anaconda).
Honestly, I would just delete anaconda. Half the people I see having difficulty compiling python modules are using anaconda.
ok thanks, I'll keep trying
I found a fix for my case (Ubuntu 16.04, python 2.7 with conda).
First, I needed to uninstall Ubuntu's Boost:
sudo apt-get remove libboost-dev
as well as conda's boost:
conda uninstall boost.
After this, dlib's setup.py identified the Boost that I had manually compiled and installed: Boost version: 1.62.0. However, there were some lingering dependencies that remained in anaconda, as indicated by: USING BOOST_LIBS: /home/jrking/anaconda/lib/_libboost_python-mt.so
I manually removed (after a backup) ~/anaconda/lib/libboost_python-mt.a and ~/home/jrking/anaconda/lib/libboost_python-mt.so
and it now seems to works.
I hope this helps others.
Sorry to necro this, but maybe my note will help someone.
I had similar error message on Debian with self-compiled Python, Boost, and dlib:
Traceback (most recent call last):
File "my_dlib_tests.py", line 102, in <module>
predictor = dlib.shape_predictor(face_landmarks_path)
Boost.Python.ArgumentError: Python argument types in
shape_predictor.__init__(shape_predictor, PosixPath)
did not match C++ signature:
__init__(boost::python::api::object, std::string)
__init__(_object*)
Based on above discussion I figured I also had compilation issue between different versions of Boost and Python. And I did have those previously due to apt-get giving different libboost version.
After fighting for hours I realized that that error is telling me that the shape_predictormethod expects a string, and I'm feeding it a pathlib.Path object. Code for clarity:
from pathlib import Path
import dlib
fname = 'shape_predictor_68_face_landmarks.dat'
# This gives the error above:
f_as_path = Path(fname)
dlib.shape_predictor(f_as_path)
# And this is the correct way to call that method:
dlib.shape_predictor(fname)
Lesson: Learn to read Boost.Python errors.
I tried all the solutions written above, but none worked on my machine.
The problem was that python from anaconda kept on find the boost version installed in anaconda.
After run the code blow and build dlib it worked.
pip uninstall dlib
conda clean --packages
So it's working now then?
@davisking Yes, I commented it for someone with the same problem.
It seems like dlib compilation does not find the right boost library if you have multiple versions installed, and ignores some of the cmake flags that allow you to _not_ use system libraries.
It can be fixed by manually fixing dlib/cmake_utils/add_python_module: set the right BOOST_LIBRARYDIR and remove FindPackage lines corresponding to the system python.
Most helpful comment
Yeah, boost.python has an awful build process. I'll switch to pybind11 instead of boost.python at some point in the future (https://github.com/davisking/dlib/issues/293). That should make building the python extensions pretty trivial.