把opencv工程移植到ROS cantkin_make中
agx(TX2)下 ROS cantkin_make编译含opencv链接库未定应引用的问题
之前在opencv上跑了一个视觉检测的工程,想把检测结果的某个数值通过ros节点发出来,就创建了一个工作空间和功能包写了个发布者节点。
重点是写catkin_make里面的cmakelist.txt
最初单独的opencv工程如下,复现这位大神的工作https://github.com/enazoe/yolo-tensorrt
cmakelist
如下
cmake_minimum_required(VERSION 3.1)
project(yolo-trt VERSION 1.0)
enable_language(CUDA)
set(CMAKE_CXX_COMPILIER "/usr/bin/g++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -Wno-write-strings")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,$ORIGIN")
#cuda
#export PATH=/usr/local/cuda-11.0/bin:$PATH
#include_directories(/usr/local/cuda/include)
#link_directories(/usr/local/cuda/lib64)
find_package(CUDA REQUIRED)
#opencv
#set(OpenCV_DIR /opt/opencv-4.1.2/share/OpenCV)
find_package(OpenCV REQUIRED)
#detector lib (cuda)
file(GLOB_RECURSE sources modules/*.hpp modules/*.cpp modules/*.h modules/*.cu extra/*.h)
add_library(detector SHARED ${sources})
target_include_directories(detector PRIVATE extra/ modules/ ${OpenCV_INCLUDE_DIRS} ${CUDA_TOOLKIT_ROOT_DIR}/include)
target_link_libraries(detector nvinfer nvinfer_plugin nvcaffe_parser "stdc++fs")
#sample
add_executable(yolo-trt samples/sample_detector.cpp)
target_include_directories(yolo-trt PRIVATE modules/ extra/)
target_link_libraries(yolo-trt detector ${OpenCV_LIBS})
可见该工程把构建构建工程的源文件都打包成了动态库还有它依赖的opencv的头文件还有cuda的头文件 还有一些nvinfer nvinfer_plugin nvcaffe_parse库都链接到了detector动态库中
然后我们看他的可执行文件是怎么构建的
target_include_directories(yolo-trt PRIVATE modules/ extra/)包含可执行文件生成需要的头文件
target_link_libraries(yolo-trt detector ${OpenCV_LIBS})链接OpenCV_LIBS库和打包生成的detector库
那么我们移植的时候只需要把生成可执行文件需要暴露的头文件(也就是可执行文件.cpp文件#include的源.h文件)以及detector拷到新的工程(ros功能包里),然后还要链接opencv库,最后进行链接编译就行了
功能包工程目录
include里面包括,extra,modules是存放头(源)文件的,一个动态库libdetector.so
cmakelist如下
cmake_minimum_required(VERSION 3.1)
project(yolo_rt)
enable_language(CUDA)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
)
set(CMAKE_CXX_COMPILIER "/usr/bin/g++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -Wno-write-strings")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,$ORIGIN")
set(OpenCV_LIB_DIR "/usr/local/share/OpenCV/")
find_package(OpenCV REQUIRED)
include_directories(
${catkin_INCLUDE_DIRS} ./include/extra ./include/modules
)
link_directories(
${catkin_LIB_DIRS} ./include ${OpenCV_LIB_DIRS}
)
add_executable(yolo_rt src/sample.cpp)
target_link_libraries(yolo_rt ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} detector
)
编译之后老是报错,是什么cv::xxxx未定义引用
[ 50%] Linking CXX executable /home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt
/home/nubot/cc/preception_ws/src/yolo_rt/./include/libdetector.so: undefined reference to `cv::dnn::dnn4_v20190621::blobFromImages(cv::_InputArray const&, double, cv::Size_<int>, cv::Scalar_<double> const&, bool, bool, int)'
collect2: error: ld returned 1 exit status
yolo_rt/CMakeFiles/yolo_rt.dir/build.make:127: recipe for target '/home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt' failed
make[2]: *** [/home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt] Error 1
CMakeFiles/Makefile2:477: recipe for target 'yolo_rt/CMakeFiles/yolo_rt.dir/all' failed
make[1]: *** [yolo_rt/CMakeFiles/yolo_rt.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
查阅资料,很多博客都说opencv库没有链接,给的都是最基本的链接方法,何况我已经链接了,所以未能解决
去ros社区看了下,有的说是ros一般会自己自带一个opencv路径,findpackage不能找到正确的opencv库路径
让我设置一下,在find前面加下路径
参考 https://answers.ros.org/question/312235/error-linking-to-opencv-dnn-library/
set(OpenCV_LIB_DIR “/usr/local/share/OpenCV/”)
find_package(OpenCV REQUIRED)
但还是报相同的错误
是不是这个路径加的也不对呢,人家是正常电脑安装的opencv库,我是ARM板子刷机的
报错是libdetector.so
没有定义cv::dnn::dnn4
,查了一下cv::dnn::dnn4
属于ibopencv_dnn
问题应该出在它没有正确链接opencv库于是跑到这个libdetector.so
库去找,那当然找不到
简单粗暴直接找这个库路径在哪
sudo find / -iname "*opencv*"
找到libopencv_dnn
,果然它不再share
里面,而在/usr/lib/aarch64-linux-gnu
里面
/usr/lib/aarch64-linux-gnu/libopencv_objdetect.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_features2d.so
/usr/lib/aarch64-linux-gnu/libopencv_imgproc.so.4.1
/usr/lib/aarch64-linux-gnu/libopencv_ml.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_videoio.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_core.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_dnn.so.4.1.1
于是cmakelist中直接target_link_libraries加入该库的绝对路径/usr/lib/aarch64-linux-gnu/libopencv_dnn.so
target_link_libraries(yolo_rt ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} detector /usr/lib/aarch64-linux-gnu/libopencv_dnn.so
)
最后catkin_make
nubot@nubot-desktop:~/cc/preception_ws$ catkin_make
Base path: /home/nubot/cc/preception_ws
Source space: /home/nubot/cc/preception_ws/src
Build space: /home/nubot/cc/preception_ws/build
Devel space: /home/nubot/cc/preception_ws/devel
Install space: /home/nubot/cc/preception_ws/install
[ 50%] Linking CXX executable /home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt
[100%] Built target yolo_rt
终于解决!
码字不易读后一赞手有余香