ROS+CMake的OpenCV版本切换(CMake Package原理讲解)

背景

由于在初学slam阶段,电脑上装了一堆开源的slam代码,每个代码的环境库都不一样,其中最重要的opencv库需要经常切换。在此期间,csdn上的很多帖子有坑,浪费了我非常多的时间,坑位总结如下:

  1. 通过.bashrc修改PKG_CONFIG_PATH和LD_LIBRARY_PATH只是修改了动态链接库,在编译程序的时候还是原来的版本。
  2. 通过.so文件直接替换,非常坑人,看起来版本都变了,但是在程序运行时还是会调用之前的链接库,这是因为package的.cmake文件中依然保存的是原来的.so路径

原因:根据项目的CMakeList里面的包,CMake会采用不同的调用策略

PackagePath
cv_bridge/opt/ros/noetic/share/cv_bridge
OpenCV/usr/local/share/OpenCV

如果,这两个文件夹里的OpenCV版本不同,那么就杯具了,程序会有莫名其妙的各种问题和Warning,而修改.bashrc的办法也只针对OpenCV而不是cv_bridge,导致版本不一致,所以这就是坑点。

OpenCV多版本安装

首先安装多版本的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

CMakeList的find_package()功能解析

find_package()这个函数的功能,是通过搜索一些路径,寻找到来实现的。搜索路径<package>Config.cmake的优先级我暂时没有做测试,但是可以粗略的做一个表格

  1. CMAKE_PREFIX_PATH
  2. <package>_DIR
  3. CMAKE_FRAMEWORK_PATH
  4. PATH

在这些路径中,寻找以下的文件夹里有没有<package>文件夹,再搜索<package>Config.cmake文件

  1. <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/
  2. <prefix>/(lib/<arch>|lib|share)/<name>*/
  3. <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/

所以,我们只需要保证CMAKE_PREFIX_PATH路径中有这些包就行,就不会找不到包了,其次,再保证OpenCV的版本正确。

项目的CMakeList编写指南

在安装了不同版本的OpenCV之后,我们需要在每个项目的CMakeList中添加

set(OpenCV_DIR "/usr/local/opencv_4.7.0")

解释:
通过message(STATUS ${CMAKE_PREFIX_DIR})可以知道,CMAKE_PREFIX_PATH的路径有:

  • /usr/local/
  • /opt/ros/noetic/

由上文的find_package()功能解析可以知道,CMAKE_PREFIX_PATH的优先级最高。

那么,我们需要确保这个OpenCV多版本的包在这两个路径下都找不到,这样我们自己设置OpenCV_DIR就能正确连接到合适的版本了。删掉这两个路径下OpenCV文件夹再进行修改CMakeList

ROS的cv_bridge安装

接下来,我们需要解决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完成安装。

总体流程

讲了这么多,总结以下,确保能够运行多版本切换的流程是:

  1. 安装多版本的opencv
  2. 确保OpenCV多版本的包在CMAKE_PREFIX_PATH路径下找不到(删去必要的部分)
  3. 在每个项目的CMakeList里面添加OpenCV_DIR
  4. 重新安装cv_bridge
  5. 完成更改

如果需要重新切换版本,需要重新安装cv_bridge

参考

  1. https://github.com/ros-perception/vision_opencv/tree/noetic
  2. https://zhuanlan.zhihu.com/p/50829542
  3. https://immortalqx.github.io/2021/07/06/opencv-notes-0/
  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CMakeList文件中使用find_package命令来查找OpenCV库时,需要根据不同的情况进行配置。如果需要使用opencv3,可以在CMakeList文件中添加以下配置内容:\[1\] ``` set(OpenCV_DIR /usr/local/share/OpenCV) # 设置opencv3的OpenCVConfig.cmake文件 find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) message(STATUS "Opencv_include_Path: " ${OpenCV_INCLUDE_DIRS}) message(STATUS "Opencv_Library_Path: " ${Opencv_LIBRARIES}) ``` 如果需要使用ROS自带的OpenCV库,可以使用以下配置内容:\[2\] ``` set(OpenCV_DIR /usr/share/OpenCV) # 设置ROS自带的OpenCV路径 find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) message(STATUS "Opencv_include_Path: " ${OpenCV_INCLUDE_DIRS}) message(STATUS "Opencv_Library_Path: " ${Opencv_LIBRARIES}) ``` 另外,在Ubuntu系统中可能会同时安装opencv3和opencv4的版本。如果需要使用opencv4,可以在CMakeList文件中添加以下配置内容:\[3\] ``` set(OpenCV_DIR /usr/lib/cmake/opencv4) # 设置opencv4的OpenCVConfig.cmake文件 find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) message(STATUS "Opencv_include_Path: " ${OpenCV_INCLUDE_DIRS}) message(STATUS "Opencv_Library_Path: " ${Opencv_LIBRARIES}) ``` 以上配置内容可以根据实际情况进行调整,确保CMake能够正确找到并链接OpenCV库。 #### 引用[.reference_title] - *1* *3* [CMakeLists中配置不同opencv版本的记录](https://blog.csdn.net/chrisspf/article/details/128640740)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [OpenCV3.4.10安装与CMakeLists编写](https://blog.csdn.net/boyhoodme/article/details/108472576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值