由于在初学slam阶段,电脑上装了一堆开源的slam代码,每个代码的环境库都不一样,其中最重要的opencv库需要经常切换。在此期间,csdn上的很多帖子有坑,浪费了我非常多的时间,坑位总结如下:
原因:根据项目的CMakeList里面的包,CMake会采用不同的调用策略
Package | Path |
---|---|
cv_bridge | /opt/ros/noetic/share/cv_bridge |
OpenCV | /usr/local/share/OpenCV |
如果,这两个文件夹里的OpenCV版本不同,那么就杯具了,程序会有莫名其妙的各种问题和Warning,而修改.bashrc的办法也只针对OpenCV而不是cv_bridge,导致版本不一致,所以这就是坑点。
首先安装多版本的OpenCV,下载不同的OpenCV版本,一定注意,需要在执行cmake指令时规定install的路径!,如下所示替换相应的路径和版本
cmake .. -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local/opencv_4.7.0 \ #把opencv安装路径
-D OPENCV_EXTRA_MODULES_PATH=/home/${主机名}/opencv_contrib-4.7.0/modules \ #指向下载的opencv_contrib文件夹
-D OPENCV_GENERATE_PKGCONFIG=YES
演示的是opencv4.7.0版本,其他版本类似操作,只需要修改CMAKE_INSTALL_PREFIX和OPENCV_EXTRA_MODULES_PATH就行。
最后别忘了sudo make install
find_package()这个函数的功能,是通过搜索一些路径,寻找到来实现的。搜索路径
的优先级我暂时没有做测试,但是可以粗略的做一个表格
CMAKE_PREFIX_PATH
_DIR
CMAKE_FRAMEWORK_PATH
PATH
在这些路径中,寻找以下的文件夹里有没有
文件夹,再搜索
文件
/(lib/|lib|share)/cmake/*/
/(lib/|lib|share)/*/
/(lib/|lib|share)/*/(cmake|CMake)/
所以,我们只需要保证CMAKE_PREFIX_PATH
路径中有这些包就行,就不会找不到包了,其次,再保证OpenCV的版本正确。
在安装了不同版本的OpenCV之后,我们需要在每个项目的CMakeList中添加
set(OpenCV_DIR "/usr/local/opencv_4.7.0")
解释:
通过message(STATUS ${CMAKE_PREFIX_DIR})
可以知道,CMAKE_PREFIX_PATH的路径有:
由上文的find_package()功能解析可以知道,CMAKE_PREFIX_PATH的优先级最高。
那么,我们需要确保这个OpenCV多版本的包在这两个路径下都找不到,这样我们自己设置OpenCV_DIR就能正确连接到合适的版本了。删掉这两个路径下OpenCV文件夹再进行修改CMakeList
接下来,我们需要解决ros系统对opencv的调用问题,首先,要删掉原本的cv_bridge
sudo apt-get remove ros-noetic-cv-bridge
下载cv_bridge源码,注意在branch中选择版本
Github 链接
修改CMakeList,指定OpenCV package的路径。
set(OpenCV_DIR "/usr/local/opencv_4.7.0")
find_package(OpenCV REQUIRED)
再进行sudo make install
完成安装。
讲了这么多,总结以下,确保能够运行多版本切换的流程是:
CMAKE_PREFIX_PATH
路径下找不到(删去必要的部分)如果需要重新切换版本,需要重新安装cv_bridge