uricamic / clandmark

Open Source Landmarking Library
http://cmp.felk.cvut.cz/~uricamic/clandmark
GNU General Public License v3.0
199 stars 111 forks source link

Relocation error when compiling Python interface on Ubuntu #77

Closed vuki closed 7 years ago

vuki commented 7 years ago

Hello. I'm trying to compile the python module for Python 3.5 on Ubuntu 16.10. It fails with the following error:

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libpython3.5m.a(abstract.o): relocation R_X86_64_PC32 against symbol `PyObject_Call' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
python_interface/src/CMakeFiles/py_featurePool.dir/build.make:108: recipe for target 'python_interface/src/py_featurePool.so' failed

Is there a way to fix it? I tried to add -fPIC to compiler flags, it didn't work.

vuki commented 7 years ago

Please disregard. I solved the issue by linking to libpython3.5m.so. Apparently, linking to libpython3.5m.a won't work.

uricamic commented 7 years ago

Hi @vuki

I think it is possible to link against the static python library, however, it would require modification of the CMakeLists.txt files for Python interface. They assume dynamic python libraries now.

vkasojhaa commented 5 years ago

Hi @vuki, I am facing similar problem to yours. Please can you explain how you resolved this issue.

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libpython3.5m.a(abstract.o): relocation R_X86_64_32S against _Py_NotImplementedStruct' can not be used when making a shared object; recompile with -fPIC /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libpython3.5m.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status python_interface/src/CMakeFiles/py_featurePool.dir/build.make:104: recipe for target 'python_interface/src/py_featurePool.so' failed make[2]: *** [python_interface/src/py_featurePool.so] Error 1 CMakeFiles/Makefile2:339: recipe for target 'python_interface/src/CMakeFiles/py_featurePool.dir/all' failed make[1]: *** [python_interface/src/CMakeFiles/py_featurePool.dir/all] Error 2 Makefile:127: recipe for target 'all' failed make: *** [all] Error 2

uricamic commented 5 years ago

Hi @vkasojhaa

seems you are trying to compile against static python library. Try to use the dynamic one (libpython3.5m.so). You can change it in advanced cmake settings. Ping me if you need help with that.

vkasojhaa commented 5 years ago

@uricamic thank you for replying.

Here are my variables in advanced cmake settings. pic1 2

I am now getting the following waning message in ccmake: warning

When I make, I get the following error: [ 78%] Building CXX object python_interface/src/CMakeFiles/py_flandmark.dir/py_flandmark.cxx.o In file included from /usr/local/include/CLandmark.h:14:0, from /home/vikas/clandmark/build/python_interface/src/py_flandmark.cxx:610: /usr/local/include/CAppearanceModel.h:21:18: fatal error: CImg.h: No such file or directory compilation terminated. python_interface/src/CMakeFiles/py_flandmark.dir/build.make:74: recipe for target 'python_interface/src/CMakeFiles/py_flandmark.dir/py_flandmark.cxx.o' failed make[2]: *** [python_interface/src/CMakeFiles/py_flandmark.dir/py_flandmark.cxx.o] Error 1 CMakeFiles/Makefile2:413: recipe for target 'python_interface/src/CMakeFiles/py_flandmark.dir/all' failed make[1]: *** [python_interface/src/CMakeFiles/py_flandmark.dir/all] Error 2 Makefile:127: recipe for target 'all' failed make: *** [all] Error 2 vikas@mettl424:~/clandmark

Note: I am able to build successfully with python_bindings: OFF. But I need to use the python inetrface.

uricamic commented 5 years ago

Hi @vkasojhaa

seems that for some reason CImg.h was not found during compile. Which is weird, since I see that you have successfully compiled CLandmark library (libclandmark.so). Check the path provided in CImg_INCLUDE_DIR, if it really contains CImg.h. It is also possible that paths are messed up in the configuration script.

The quick and dirty solution could be copying this file inside /usr/local/include as you have this path specified for CLANDMARK_INCLUDE_DIR. I will check the scripts when I get to my pc at home.

uricamic commented 5 years ago

@vkasojhaa

indeed, I located a suspicious line in the configuration script (https://github.com/uricamic/clandmark/blob/947a3da11bd6a80926fe13119cd5041234e9493e/python_interface/CMakeLists.txt#L12) maybe simply uncommenting this line could solve your issues. However, I cannot check it right now myself.

vkasojhaa commented 5 years ago

@uricamic Uncommenting the lines you said didn't solve the issue but I got away with the error by copying the files into CLANDMARK_INCLUDE_DIR. Now, I am getting this error when I make: `[100%] Built target clandmark [100%] Built target flandmark [100%] Built target static_input [100%] Built target video_input [100%] Built target ReplicatePythonSourceTree [100%] Built target py_featurePool [100%] Built target py_flandmark [100%] Built target python_interface [100%] Linking CXX executable flandmark-demo

CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_13get_model_parameters_dimension(_object*, _object*)': py_flandmark_static.cxx:(.text+0x3d3d): undefined reference toclandmark::CLandmark::computeWdimension()' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_27getBaseWindowSize(_object*, _object*)': py_flandmark_static.cxx:(.text+0x3dbb): undefined reference toclandmark::Flandmark::getBaseWindowSize()' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_tp_new_12py_flandmark_PyFlandmark(_typeobject*, _object*, _object*)': py_flandmark_static.cxx:(.text+0x4f0b): undefined reference toclandmark::Flandmark::Flandmark(char const, bool)' py_flandmark_static.cxx:(.text+0x4f81): undefined reference to `clandmark::Flandmark::Flandmark(char const, bool)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_25getSearchSpace(_object*, _object*)': py_flandmark_static.cxx:(.text+0x560d): undefined reference toclandmark::Flandmark::getSearchSpace(int)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_15set_weights_parameters(_object*, _object*)': py_flandmark_static.cxx:(.text+0x5ebc): undefined reference toclandmark::CLandmark::computeWdimension()' py_flandmark_static.cxx:(.text+0x5f84): undefined reference to clandmark::CLandmark::setW(double*)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In functionpyx_pw_12py_flandmark_11PyFlandmark_17write(_object, _object, _object)': py_flandmark_static.cxx:(.text+0x6b28): undefined reference to `clandmark::CLandmark::write(char const, bool)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function `pyx_pw_12py_flandmark_11PyFlandmark_23setLossTable(_object, _object, _object)': py_flandmark_static.cxx:(.text+0x7a36): undefined reference to `clandmark::Flandmark::setLossTable(double, int)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_7detect_base(_object*, _object*, _object*)': py_flandmark_static.cxx:(.text+0x8630): undefined reference toclandmark::CLandmark::detect_base(cimg_library::CImg, int)' py_flandmark_static.cxx:(.text+0x9542): undefined reference to clandmark::CLandmark::detect_base(cimg_library::CImg<unsigned char>*, int*)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In functionpyx_pw_12py_flandmark_11PyFlandmark_31detect_optimized(_object, _object, _object)': py_flandmark_static.cxx:(.text+0xaeb4): undefined reference to `clandmark::CLandmark::detect_optimized(cimg_library::CImg, int, double)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_21get_psi(_object*, _object*, _object*)': py_flandmark_static.cxx:(.text+0xd33d): undefined reference toclandmark::CLandmark::getFeatures(int)' py_flandmark_static.cxx:(.text+0xd349): undefined reference to clandmark::CLandmark::computeWdimension()' py_flandmark_static.cxx:(.text+0xe6d9): undefined reference toclandmark::CLandmark::getFeatures(cimg_library::CImg, int, int)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function __pyx_pw_12py_flandmark_11PyFlandmark_19get_psi_base(_object*, _object*, _object*)': py_flandmark_static.cxx:(.text+0xf6a7): undefined reference toclandmark::CLandmark::computeWdimension()' py_flandmark_static.cxx:(.text+0x104fe): undefined reference to clandmark::CLandmark::getFeatures_base(cimg_library::CImg<unsigned char>*, int*)' py_flandmark_static.cxx:(.text+0x1050a): undefined reference toclandmark::CLandmark::computeWdimension()' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function `__pyx_pf_12py_flandmark_11PyFlandmark_8get_normalized_frame(pyx_obj_12py_flandmark_PyFlandmark, tagPyArrayObject_fields, _object, tagPyArrayObject_fields)': py_flandmark_static.cxx:(.text+0x125e2): undefined reference to clandmark::Flandmark::getNF(cimg_library::CImg<unsigned char>*, int*, double*)' py_flandmark_static.cxx:(.text+0x133e0): undefined reference toclandmark::Flandmark::getNF(cimg_library::CImg, int, double)' CMakeFiles/flandmark-demo.dir/py_flandmark_static.cxx.o: In function `__pyx_pw_12py_flandmark_11PyFlandmark_5detect(_object, _object, _object)': py_flandmark_static.cxx:(.text+0x158fb): undefined reference to clandmark::CLandmark::detect(cimg_library::CImg<unsigned char>*, int*, double*)' collect2: error: ld returned 1 exit status python_interface/bin/CMakeFiles/flandmark-demo.dir/build.make:138: recipe for target 'python_interface/bin/flandmark-demo' failed make[2]: *** [python_interface/bin/flandmark-demo] Error 1 CMakeFiles/Makefile2:468: recipe for target 'python_interface/bin/CMakeFiles/flandmark-demo.dir/all' failed make[1]: *** [python_interface/bin/CMakeFiles/flandmark-demo.dir/all] Error 2 Makefile:127: recipe for target 'all' failed make: *** [all] Error 2

uricamic commented 5 years ago

Hi @vkasojhaa

this looks quite weird. It seems that you are compiling against static libclandmark. One thing I noticed in the screenshots from CMake is that you are having CLANDMARK_LIBRARY_SHARED set to /usr/local/lib/libclandmark.so. Have you compiled and also installed the library first? I am asking becasue the CLANDMARK_LIBRARY_STATIC you have set to a different folder (btw there should be libclandmark.a not just a folder there).

Anyway, please write me email to uricar.michal@gmail.com with description of steps you made so far, so I can try to reproduce it on my computer.

In the worst case, I can compile it on my pc and share the binaries with you. That should work for sure.

uricamic commented 5 years ago

Hi again @vkasojhaa,

I just noticed that according to the output, you should have the necessary files (python interface) produced. The error happened when compiling some demo script. Can you try to run the enclosed ipython notebook (with modifications of paths, where necessary) to try it out?

vkasojhaa commented 5 years ago

@uricamic I tried to run the enclosed ipython notebook but I got an import error for 'py_flandmark'. Can you tell what path I should add. In "webcam_input.py" file you have added the path sys.path.append("D:/GitHub/clandmark/install/share/clandmark/python/") which I think was for Windows. Here is the error I am getting.

`ImportError Traceback (most recent call last) in 1 import os, sys 2 sys.path.append("/home/vikas/clandmark/python_interface/") ----> 3 from py_flandmark import PyFlandmark 4 from py_featurePool import PyFeaturePool

ImportError: No module named 'py_flandmark'`

uricamic commented 5 years ago

Hi @vkasojhaa

you need to have the py_flandmark.so and py_featurePool.so in that path, it should be in your build folder somewhere. These two files form the python interface, actually.

vkasojhaa commented 5 years ago

Hi @uricamic I found py_flandmark.so in /clandmark/build/python_interface/src/ dir, but I can't seem to find py_featurePool.so anywhere, maybe because I coudn't build successfully with Python_bindings. Anyways, I added the path to /clandmark/build/python_interface/src/. But now I am having this error. I am guessing this is due to unsuccessful build.

`ImportError Traceback (most recent call last) in 1 import os, sys 2 sys.path.append("/home/vikas/clandmark/build/python_interface/src/") ----> 3 from py_flandmark import PyFlandmark 4 from py_featurePool import PyFeaturePool

ImportError: /home/vikas/clandmark/build/python_interface/src/py_flandmark.so: undefined symbol: _ZN9clandmark9CLandmark5writeEPKcb`

vkasojhaa commented 5 years ago

@uricamic I got the build successfully. I gave the path to individual file libclandmark.a in place of directory for CLANDMARK_LIBRARY_STATIC and it compiled fine. I tested the webcam_input.pyusing CDPM.xml model and it is taking 33ms per frame.

I have a query. I see that the model is not working for some pose variation. Is this due to the face detector, if so can I use my own face detector. Also I see three pre-trained models, I have use case where I have images with pose and occlusion and I need 5 facial landmarks in real time, which model should I prefer.

Anyways, thank you for the guidance, highly appreciated.

uricamic commented 5 years ago

Hi @vkasojhaa,

ok, I just figured out that the build system is outdated and needs some updates. However, try to do this:

  1. create new build folder within clandmark folder.
  2. call ccmake .. from this new build folder.
  3. Toggle advanced mode on (press t in ccmake).
  4. Change CMAKE_INSTALL_PREFIX to some local path, e.g. install folder within clandmark folder (e.g. /home/vikas/clandmark/install).
  5. Leave all BUILD_* fields in ccmake OFF
  6. Configure ccmake and Generate build scripts.
  7. Run make and then make install.
  8. Now turn only BUILD_SHARED_LIBS ON.
  9. Configure ccmake and Generate build scripts.
  10. Run make and then make install.
  11. Now you can turn BUILD_PYTHON_BINDINGS ON.
  12. Configure ccmake and Generate build scripts.
  13. Try make. It should give you an error that CImg.h was not found.
  14. Copy CImg.h from 3rd_party/CImg-1.5.6/ and all *.hpp filed from 3rd_party/rapidxml-1.13/ to your CMAKE_INSTALL_PREFIX path (to the include folder there, to be more precise, there should be other .h files from CLandmark already, e.g. CLandmark.h).
  15. Now the make should work, as well as make install.

Then you should be able to find those files.

uricamic commented 5 years ago

Hi @vkasojhaa

happy to hear that :)

Yeah, it could be due to the facial detector misalignment or due to the severe head rotation. There are different models available which can actually also predict the headpose and work even on profile faces. If you need some specific format of landmarks. The best would be to train your own model. I would need a bit more details to actually recommend something. There is a model with 7 landmarks only, which works fairly well on near frontal faces and it takes just around 3ms to detect those. However, if you need something that works also on profile faces, it would be best to define multi-view configuration for your setup of landmarks. I have some model which detectd up to 21 landmarks and works multi-view.

vkasojhaa commented 5 years ago

@uricamic I checked the Joint multi-view facial landmark detector model and it gives the landmarks I need and it is taking around 2.5ms. Now, I see there are 5 models in jointmv_models depending on the view. Can you tell how to use the multi-view configuration for this model. I see C++ code snippet for the model here. I want to know how to choose one of the 5 models depending on the view. Perhaps, if there is any available python code snippet for this.

uricamic commented 5 years ago

Hi @vkasojhaa

there is no Python script for this at the moment. However, I can try to prepare it in the evening (hope I will get some time for that). It will altogether take around 12 ms, as all the models need to be run in order to estimate the correct viewport (head orientation). However it is also possible to use this information from other source (e.g. from the face detector), if available.

vkasojhaa commented 5 years ago

@uricamic Thank you for the info, 12ms seems good for the combined models. Also, it will be really helpful if you can get some time for the Python script. I will try to use my custom trained face detector and see the performance.

uricamic commented 5 years ago

Hi @vkasojhaa

sorry, I din't get to the scripts yet. I hope I will find some time over weekend.

uricamic commented 5 years ago

Hi @vkasojhaa

I experienced some problems compiling python interface on my machine (win10, visual studio 2017), so it will take me some more time. Sorry for that.

vkasojhaa commented 5 years ago

Hi @uricamic No problem, and thanks for taking time for this.

uricamic commented 5 years ago

Hi @vkasojhaa

I finally got to solve the build issues on my new system. I have created a new python example, where multi-view model is used, you can check it here: https://github.com/uricamic/clandmark/blob/29ce0c9460f376cd6676e0821668b1e9bed38594/python_interface/examples/webcam_input_jointmv.py#L40

However, you will have to rebuild the Python interface, as one important function was not ported: https://github.com/uricamic/clandmark/blob/29ce0c9460f376cd6676e0821668b1e9bed38594/python_interface/examples/webcam_input_jointmv.py#L48

However, it is needed only if you are interested also in the viewport estimation. If not, you can simply select landmarks from any of the flandmark instances in the pool (e.g. if you have other source of viewport estimation). In such case, you can simply omit the get_score() function call from your script.