ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

Standalone OpenCV

asked 2014-02-12 05:36:02 -0600

Jep gravatar image

updated 2014-02-12 22:33:40 -0600

bchr gravatar image

This is an old question, but I couldn't find any good solution.

I have recently installed the latest (unrealesed) OpenCV 3.0 in my machine for some programs. Nothing related with ROS at all. This OpenCV version is installed at /usr/local as usual.

The thing is that, when trying to compile my code, cmake always find the ROS groovy OpenCV version (2.X) and fails. The only way I can compile it is uninstalling ROS OpenCV version or renaming it.

I have tried instead of:

find_package( OpenCV REQUIRED )
target_link_libraries( foo ${OpenCV_LIBS} )

Using:

include_directories(/usr/local/include usr/local/include/opencv2 usr/local/include/opencv)
link_directories(/usr/local/lib)
target_link_libraries( foo opencv_core opencv_highgui opencv_imgproc)

But, no result. Any ideas?

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
0

answered 2014-02-12 21:14:24 -0600

Jep gravatar image

updated 2014-02-17 03:36:53 -0600

Thanks to both for your help. I've tried the bchr first approach, and it looks like it finds properly the new OpenCV installation. But, there's something more here. Without ROS opencv it compiles without problem:

-- OpenCV Root directory is /usr/local/share/OpenCV
-- OpenCV include directories are /usr/local/include/opencv
-- OpenCV libs directory is: /usr/local/lib/libopencv_core.so.3.0.0;/usr/local/lib/libopencv_imgproc.so.3.0.0;/usr/local/lib/libopencv_highgui.so.3.0.0;/usr/local/lib/libopencv_ml.so.3.0.0;/usr/local/lib/libopencv_video.so.3.0.0;/usr/local/lib/libopencv_features2d.so.3.0.0;/usr/local/lib/libopencv_calib3d.so.3.0.0;/usr/local/lib/libopencv_objdetect.so.3.0.0;/usr/local/lib/libopencv_contrib.so.3.0.0;/usr/local/lib/libopencv_legacy.so.3.0.0;/usr/local/lib/libopencv_flann.so.3.0.0

When ROS opencv is installed, it fails to compile:

foo.cpp:(.text+0x661): undefined reference to `cv::_OutputArray::_OutputArray(cv::Mat&)'

But the includes and libraries variables are the same!!

-- OpenCV Root directory is /usr/local/share/OpenCV
-- OpenCV include directories are /usr/local/include/opencv
-- OpenCV libs directory is /usr/local/lib/libopencv_core.so.3.0.0;/usr/local/lib/libopencv_imgproc.so.3.0.0;/usr/local/lib/libopencv_highgui.so.3.0.0;/usr/local/lib/libopencv_ml.so.3.0.0;/usr/local/lib/libopencv_video.so.3.0.0;/usr/local/lib/libopencv_features2d.so.3.0.0;/usr/local/lib/libopencv_calib3d.so.3.0.0;/usr/local/lib/libopencv_objdetect.so.3.0.0;/usr/local/lib/libopencv_contrib.so.3.0.0;/usr/local/lib/libopencv_legacy.so.3.0.0;/usr/local/lib/libopencv_flann.so.3.0.0

EDITED:

Ok! Ive done some good progress. The problem is that ROS sets the CPATH environment variable as:

echo $CPATH 
/usr/local/include:/home/jep/catkin_ws/devel/include:/opt/ros/groovy/include

So, even if you include the correct headers gcc wil always find the old ones if you don't delete the CPATH variable... I've tried adding /usr/local/include to CPATH, but the same behaviour appears, it only seems to work unsetting CPATH... Any ideas? I would like to keep CPATH as it is to avoid breaking anythin when I need to use ROS!

edit flag offensive delete link more

Comments

Try to use make in verbose mode, get the exact compilation command used by gcc, and paste it here. It may also help us if you give us more information on the rest of your CMakeLists.txt.

bchr gravatar image bchr  ( 2014-02-12 22:13:40 -0600 )edit

thanks! II've edited the answer

Jep gravatar image Jep  ( 2014-02-14 03:50:06 -0600 )edit

You can probably overwrite CPATH in your CMakeLists.txt only, so that this does not affect whatever you do after. You can access it with $ENV{CPATH}, you could try to save it and set it back at the end.

bchr gravatar image bchr  ( 2014-02-14 04:06:31 -0600 )edit

Still, the fact that OpenCV 3 precedes ROS' OpenCV in your path, yet this still fails, is quite surprising (if you do not use OpenCV2-only headers, obviously).

bchr gravatar image bchr  ( 2014-02-14 04:21:38 -0600 )edit

Yep... It's very strange for me. I don't understand it always find opencv2 headers even if setting /usr/local/include to CPATH as well... I've tried unsetting CPATH from CMakeLists but it didn't work... Seems that setting them in CMakeLists it's only somehow temporal... Thanks!

Jep gravatar image Jep  ( 2014-02-17 03:36:15 -0600 )edit

Could you post your FindOpenCV3.cmake file? I'm have the same trouble...

J.M.T. gravatar image J.M.T.  ( 2015-06-02 02:50:21 -0600 )edit
1

answered 2014-02-12 06:15:57 -0600

bchr gravatar image

updated 2014-02-12 09:19:36 -0600

Apparently, the CMake "find_package scripts" for OpenCV installed by ROS rely on their own path to find OpenCV:

# Extract the directory where *this* file has been installed (determined at cmake run-time)
get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE)
set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../../..")

If you use your own FindOpenCV.cmake instead, you should be able to find your actual OpenCV installation without relying on hardcoded values in your CMakeLists.txt.

You can try to get a generic FindOpenCV.cmake (maybe this one), put it in your CMake modules directory, and then (before calling find_package):

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/path/to/your/cmake_modules/directory ${CMAKE_MODULE_PATH}) 
find_package(OpenCV REQUIRED)
...
target_link_libraries(foo ${OpenCV_LIBS})

Note that you need to make sure that the first FindOpenCV.cmake CMake finds is yours, else it will fall back on ROS' OpenCV. You can check this Stack Overflow post for more information. The rest depends on your FindOpenCV.cmake, you just need to read the documentation at the beginning to see the variables that may need to be set.

Another solution would be to use pkg-config if OpenCV 3 is installed with pkg-config support.

# You can set PKG_CONFIG_PATH if opencv.pc is in an unusual location. Note that pkg-config will
# look for opencv.pc in all the directories in this path, and stop at the first opencv.pc file found.
# You can probably try something like:
# set(ENV{PKG_CONFIG_PATH} ${OpenCV_DIR}/lib/pkgconfig:ENV{PKG_CONFIG_PATH})
find_package(PkgConfig REQUIRED)
pkg_check_modules(OpenCV REQUIRED opencv >= 3)
# OpenCV_FOUND: OpenCV found on the system
# OpenCV_INCLUDE_DIRS: OpenCV include directories 
# OpenCV_LIBRARIES: libraries for linking in order to use OpenCV
# OpenCV_LIBRARY_DIRS: OpenCV library directories

If you have both opencv.pc installed (one for OpenCV 2, one for OpenCV 3), you may want to rename OpenCV 3's file opencv3.pc, and use pkg_check_modules(OpenCV REQUIRED opencv3) instead. You could also use this pkg-config method and put that in a FindOpenCV3.cmake script (e.g. this script that can be adapted easily).

edit flag offensive delete link more
1

answered 2014-02-12 08:03:23 -0600

ahendrix gravatar image

I suspect you're going about this the right way by manually specifying include and library directories. It won't be portable or installable elsewhere, but it should get you off the ground and allow you to experiment with OpenCV3 on your own system.

My best guess is that the search paths are getting passed to the compiler in the wrong order, and it's searching the ROS include path before the opencv paths that you're specifying.

Try moving your include_directories() and link_directories() statements as far up your CMakeLists.txt as you can; preferably before your find_package(catkin ...)

It may also be worth running catkin_make with VERBOSE=1 so that you can examine the exact arguments that are being passed to the compiler and the linker.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2014-02-12 05:36:02 -0600

Seen: 4,857 times

Last updated: Feb 17 '14