Rosanswers logo

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} )


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

But, no result. Any ideas?

Originally posted by Jep on ROS Answers with karma: 195 on 2014-02-12

Post score: 3


3 Answers 3


Rosanswers logo

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)
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).

Originally posted by bchr with karma: 596 on 2014-02-12

This answer was NOT ACCEPTED on the original site

Post score: 1


Rosanswers logo

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.

Originally posted by ahendrix with karma: 47576 on 2014-02-12

This answer was NOT ACCEPTED on the original site

Post score: 1


Rosanswers logo

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


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

echo $CPATH 

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!

Originally posted by Jep with karma: 195 on 2014-02-12

This answer was ACCEPTED on the original site

Post score: 0

Original comments

Comment by bchr on 2014-02-12:
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.

Comment by Jep on 2014-02-14:
thanks! II've edited the answer

Comment by bchr on 2014-02-14:
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.

Comment by bchr on 2014-02-14:
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).

Comment by Jep on 2014-02-17:
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!

Comment by J.M.T. on 2015-06-02:
Could you post your FindOpenCV3.cmake file? I'm have the same trouble...


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.