OpenCV使用疑难
OpenCV的使用还包括OpenCV_contrib(扩展包)
1 版本问题
本文使用的基本都是ROS noetic自带的OpenCV自带的4.2版本
//下面这些头文件是OpenCV 2.x时代的,已经在OpenCV 3.x和之后的版本之中被移除了
#include <opencv/cv.hpp>
#include <opencv/cv.h>
//应该改为下面这个头文件
#include <opencv2/opencv.hpp>
- opencv和opencv2表示底层C API和C++ API区别
- .hpp与.h文件类似,但.hpp会将*.cpp中的实现代码也写入其中
2 引入第三方库
以引入cv::line_descriptor为例(其在OpenCV_contrib中),将其编译为静态库(.a)引入,主要通过给line_descriptor写个CMakeList.txt和节点的CMakeLists.txt中加入add_subdirectory()
3 多版本OpenCV共存问题
ros-noetic自带OpenCV 4.2,但是lsd线特征因为license问题在OpenCV 4.6.0才解决,故本教程主要解决安装在/usr/local/lib 的OpenCV-4.6.0和安装在/usr/lib的OpenCV-4.2的共存问题
- set(OpenCV_DIR …)
设置的是OpenCVConfig.cmake文件路径,而.cmake文件规定了OpenCV_LIBS(库名但不包含路径)和OpenCV_INCLUDE_DIRS(头文件路径等变量)
但要注意,.cmake不定义OpenCV_LIBRARY_DIRS(链接库的目录)
set(OpenCV_DIR /usr/local/share/OpenCV)
find_package(OpenCV REQUIRED) # 该命令引入.cmake定义的变量
message(WARNING "vins_estimator OpenCV_VERSION: ${OpenCV_VERSION}")
include_directories(${OpenCV_INCLUDE_DIRS}) # 设置OpenCV的头文件路径
set(OpenCV_LIBRARY_DIRS /usr/local/lib) # 设置OpenCV的链接库路径
link_directories(${OpenCV_LIBRARY_DIRS})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
- cv_bridge库
一般来说,上面设置的已经非常明确了,不会再出现依赖OpenCV-4.2.0的情况,但还是会有例外的,VINS会用到cv_bridge库,而ROS的cv_bridge依赖OpenCV-4.2.0构建,因此在构建libvins.so时仍然会混合链接两个OpenCV版本
解决办法是从源码编译cv_bridge并绑定OpenCV-4.6.0,在cv_bridge的CMakeLists.txt里增加下面两行,cv_bridge只能通过catkin_make构建,要确保把libcv_bridge.so安装到/usr/local/lib下。
set(CMAKE_PREFIX_PATH "/usr/local")
set(OpenCV_DIR /usr/local/lib/cmake/opencv4) #根据实际.cmake路径修改
可以通过ldd libcv_bridge.so |grep opencv
查看.so是否链接到OpenCV-4.6.0
然后修改VINS的CMakeLists.txt,让其链接到/usr/local/lib/libcv_bridge.so
、