How to correctly link opencv3 under ROS Indigo (using CMake)?
Am not being able to link opencv3 that I installed myself separately from ros. Am getting this error
../devel/lib/libirTest.so: undefined reference to `cv::ORB::create(int, float, int, int, int, int, int, int, int)'
../devel/lib/libirTest.so: undefined reference to `cv::calcOpticalFlowPyrLK(cv::_InputArray const&, cv::_InputArray const&, cv::_InputArray const&, cv::_InputOutputArray const&, cv::_OutputArray const&, cv::_OutputArray const&, cv::Size_<int>, int, cv::TermCriteria, int, double)'
HOWEVER, am able to succefully compile outside ROS; that is, using the similar package without ROS.... Here is the CMake file am using under ROS (that does not work)
cmake_minimum_required(VERSION 2.8.3)
project(my_test_pkg)
SET(SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
find_package(catkin REQUIRED COMPONENTS
cv_bridge
image_transport
roscpp
rospy
std_msgs
message_generation
genmsg
)
find_package(nodelet REQUIRED)
################################################
## Declare ROS messages, services and actions ##
################################################
add_message_files(
FILES
velocity_trsl.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS message_generation cv_bridge image_transport roscpp rospy std_msgs
)
###########
## Build ##
###########
include_directories(
${catkin_INCLUDE_DIRS}
)
#***********************
#****** GSL
#***********************
find_package( PkgConfig REQUIRED)
pkg_check_modules( gsl REQUIRED gsl )
#***********************
#****** Boost
#***********************
SET (BOOST_DIR "/home/polar/soft/lib/boost/boost_1_61_0")
FIND_PACKAGE(Boost 1.61.0 REQUIRED thread)
if (NOT Boost_FOUND)
message(FATAL_ERROR " Fatal error: Boost (version >= 1.55) required.")
else()
message(STATUS "Setting up BOOST")
message(STATUS " Includes - ${Boost_INCLUDE_DIRS}")
message(STATUS " Library - ${Boost_LIBRARY_DIRS}")
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
endif (NOT Boost_FOUND)
#***********************
#****** OpenCV
#***********************
find_package( OpenCV 3.1.0 REQUIRED )
find_package( OpenCV 3.1.0 REQUIRED PATHS /home/polar/soft/lib/opencv/opencv-3.1.0/cmake)
if (NOT OpenCV_FOUND)
message(FATAL_ERROR "*****!!!!! opencv NOT found.")
endif (NOT OpenCV_FOUND)
#****************************************
include_directories(${SRC}/calculus)
SET(MY_LIB
irTest
)
# ALL EXEC FILES...
SET(EXE_TESTER
tester1
)
add_executable(tester1 ${CMAKE_CURRENT_SOURCE_DIR}/exe-main-files-stdl/testdir/tester1.cpp )
SET(FILES_2_RUN
${EXE_TESTER}
)
#--------------------------
foreach(file2link ${FILES_2_RUN})
target_link_libraries(${file2link}
${catkin_LIBRARIES}
${Boost_LIBRARIES}
${gsl_LIBRARIES}
${OpenCV_LIBRARIES}
${OpenCV_LIBS}
${MY_LIB}
)
add_dependencies(${file2link} my_test_pkg_generate_messages_cpp)# newlly added for messages!!
endforeach(file2link)
add_subdirectory(src)
Should it be a conflict between the opencv version am using and that (v2.4) used by ROS? Perhaps cv_bridge or image_transport are creating this problem... (???) I even deleted build/ and devel/ and tried to compile again, but always the same problem..... I never spent such long time than with this problem...
I was able to link a ROS project with opencv 3.1 under ROS indigo. Note that opencv 2.4 is still the default version under indigo, so this gets tricky and thus YMMV.
First, you need to have ros-indigo-opencv3
package installed. It's possible that a from-source path can work by specifying the path manually as you have done, but I haven't tested it.
In your CMakeLists.txt make sure you include ${OpenCV_INCLUDE_DIRS}
and link with ${OpenCV_LIBRARIES}
:
find_package(OpenCV 3 REQUIRED)
include_directories(
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)
add_library(your_node src/your_node.cpp)
target_link_libraries(your_node ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} )
Lastly, because the ros opencv bindings are compiled only for opencv 2.4, you need to clone the vision_opencv repository (https://github.com/ros-perception/vision_opencv) into your workspace before compiling. This will ensure the bindings link with opencv 3.
I am using both Opencv2.4.8
and opencv3.1
with ros indigo
. The opencv3.1
is installed from source under home directory- /home/xxx/opencv3_install
.
The advantage is that my older package using opencv2.4.8
doesn't need to change any code, because the default opencv version is 2.4.8
.
When opencv3.1
is needed, the CMAKE_PREFIX_PATH
should be set to find the lib.
set(CMAKE_PREFIX_PATH "/home/xxx/opencv3_install")
find_package(OpenCV 3.1 REQUIRED)
set(OpenCV_INCLUDE_DIRS "/home/xxx/opencv3_install/include")
Additionally, the cv_bridge
need to be recompiled after installing opencv3.1
.