cv_bridge与opencv版本不一致导致程序编译错误及无法运行程序问题的解决方案(附带ORB_SLAM3案例))

目录

1、问题描述

开发环境

我的程序配置

2、问题造成的后果

3、解决方案

说明:

4、实例,针对ORB_SLAM3问题

5、其他参考解决方案

6、另一个例程

7、其他:修改系统默认链接的cv_bridge版本号,以及查看当前系统链接的cv_bridge版本号与位置


与本篇问题相关的一个问题,可参考我之前的一篇博客: 

cv_bridge与python版本问题导致编译错误error: return-statement with no value, in function returning ‘void*’

 

1、问题描述

以下为我个人的开发环境用到这个问题,当然,换做其他开发环境遇到的问题也是类似的,解决方案也是类似的,因此本文问题及解决方案是通用的。

开发环境

嵌入式主控:nvidia xavier 

os:ubuntu 18.04, ROS melodic

--------------------------------------------

  • ros melodic默认安装opencv3.2
  • 由于我需要用到zed相机,因此在xavier上安装了CUDA10.0,并默认安装了opencv4.1.1
  • 另外,我还自己安装了一个opencv版本opencv3.4.9

所以,我的xavier上总共有3个版本的opencv:3.2, 4.1.1, 3.4.9

教训:以后不要在同一个主控上安装多个版本opencv,那是自找麻烦,涉及到各种配置,配置不对就导致程序无法运行,调试配置花费大量精力!

我的程序配置

在我的ROS节点程序对应的cmakelists.txt中find_package(),我用的是find_package(OpenCV 4 REQUIRED),如果用3就导致程序根本编译不通过,

因此只能选择调用opencv4库,这就是导致用户程序调用的opencv库版本4.1.1与ROS默认安装的cv_bridge调用的opencv库版本3.2不一致问题!

一句话总结:ROS melodic默认安装cv_bridge版本为1.13.0以及opencv版本为3.2,而我的程序中用到了cv_bridge且设置调用的opencv版本为4.1.1

 

2、问题造成的后果

cv_bridge与opencv版本问题会导致用户代码编译成功,但运行报错的问题,是很棘手的一个问题。

例如:

  1. 导致跑ORB_SLAM2/3失败
  2. 跑用户自己写的基于opencv库函数的程序失败

等等

——以下展示了ORB_SLAM3编译其ROS例程结果,只有几个节点编译成功,其他节点报出由于opencv版本冲突问题导致编译失败错误。

 

3、解决方案

由于我的程序或ORB_SLAM2/3都只能使用opencv4才能编译通过,因此解决方案只能是安装使用了opencv4的cv_bridge。

ROS noetic默认安装的cv_bridge1.15.0以及opencv4.2,因此,就要下载1.15.0版本的cv_bridge源码,将其放到用户自建的ROS工作空间中用

catkin_make编译,之后将用户ROS节点程序设置为优先链接用户安装的这个版本cv_bridge(而不是ROS默认安装的那个),在~/.bashrc文件中

将用户ROS工作空间包的setup.bash文件在最后source就能够覆盖ROS系统默认的cv_bridge了,并在ROS包对应的camkelists.txt中更新为find_package(OpenCV 4 REQUIRED)

总结一下,解决步骤:

  1. 下载1.15.0版本的cv_bridge源码,catkin_make编译
  2. ~/.bashrc中source上步安装的cv_bridge包路径
  3. camkelists.txt中更新find_package(OpenCV 4 REQUIRED)

说明:

(1)cv_bridge包包含在vision_opencv包中,因此,建议将vision_opencv包一起下载下来整体编译安装

注意,下载源码时选择noetic对应的1.15.0版本的!

http://wiki.ros.org/vision_opencv

(2)在cv_bridge源码目录下CHANGELOG.rst文件中有其版本更新信息,如下图所示:

 

4、实例,针对ORB_SLAM3问题

按照以下修改进行操作,即可保证正常运行

(1)修改~/.bashrc文件

按照官网(https://github.com/UZ-SLAMLab/ORB_SLAM3)将ROS包路径添加到此文件中,添加完成如下:

终端重新source ~/.bashrc

说明:

——由于我自己安装的1.15.0版本的cv_bridge安装在~/bluerov2/src下,而我没有把此包路径在bashrc进行source,因而默认调用cv_bridge版本依然是

ROS默认安装的1.13.0版本,如此这样,也未导致ORB_SLAM3的ROS包编译出错,并且ORB_SLAM3的ROS节点可以正常运行(好神奇,此问题需要

抽时间再好好研究一下,此处既然不需要一定调用1.15.0版本的cv_bridge,那么我们就可以不在bashrc中source其包路径了)。

——但是,如果编译时报错,还是建议在bashrc中将用户自己安装的cv_bridge1.15.0路径进行source一下,从而保证默认调用的是用户自己安装的cv_bridge1.15.0

——用指令pkg-config --modversion cv_bridge查看目前系统中默认的cv_bridge版本号,pkg-config --cflags cv_bridge查看系统默认搜索cv_bridge的路径

——下面分别展示了设置系统没有调用用户自己安装的cv_bridge1.15.0(本例使用),以及默认调用了用户自己安装的cv_bridge1.15.0的截图

(2)修改find_package()默认链接opencv4

将源码顶层cmakelists.txt中的find_package(OpenCV 3)修改为find_package(OpenCV 4),下面左图

将例程ROS包中的cmakelists.txt中的find_package(OpenCV 3)修改为find_package(OpenCV 4),下面右图

            

(3)将源码中opencv3库API替换成opencv4库API

在ORB_SLAM3整个工程中查找关键字CV_LOAD_IMAGE_UNCHANGED,并替换为cv::IMREAD_UNCHANGED

说明:如果不做此步修改而直接编译的话,会报错未定义的CV_LOAD_IMAGE_UNCHANGED。这是由于CV_LOAD_IMAGE_UNCHANGED是opencv3库中的,

而cv::IMREAD_UNCHANGED是opencv4库中的。

——CV_LOAD_IMAGE_UNCHANGED未定义错误

——IMREAD_UNCHANGED必须加上cv::域名(不要参考博客Ubuntu安装ORB-SLAM常见问题中说的加一个cv声明,在哪些文件加,这是个问题)

 

(4)重新编译

执行./build.sh和./build_ros.sh分别来编译ORB_SLAM3源码及ROS例程包源码。

以下展示了编译结果OK,虽然有opencv版本冲突问题,但不影响程序正常运行!

(5)运行ORB_SLAM3的ROS包例程

这里以运行Mono节点为例(使用ZED相机及对应的内参),效果如下:

——

将rosrun写成shell脚本,省去每次重新敲代码:我增加了以下文件:(1)单目节点启动shell脚本,rosrun_mono.sh(2)zed相机单目配置文件,zed_mono.yaml

运行其他相机模式的方式类似,不再赘述。

——

由于ORB_SLAM3没有将相机最终位姿以ROS话题形式发布出来,这里我自己实现了将相机位姿以变换矩阵形式发布出来了(稍后会更新成nav_msgs::Odomtry格式发布)。

单目初始化未成功阶段:无有效的相机位姿

——

定位追踪过程:相机位姿以变换矩阵形式被实时发布出来了,便于其他ROS节点订阅以实现ORB_SLAM与其他功能模块的集成

 

5、其他参考解决方案

以下为我参考的一些解决方案,都不完整,或不是很好的解决方案,本文结合自己的应用程序汇总整理出一套完整可用的解决方案

Ubuntu安装ORB-SLAM常见问题

(十一)ORBSLAM2在ROS下运行

Opencv 图像读取与保存问题

 

6、另一个例程

另外一个遇到本文同样问题的例程是我自己写的基于opencv和点云库多模态模板检测与跟踪程序,

解决方案同上,具体不再赘述,给出更新可用的一些配置截图。以下find_package(OpenCV REQUIRED)链接的是opencv4

 

7、其他:修改系统默认链接的cv_bridge版本号,以及查看当前系统链接的cv_bridge版本号与位置

(1)如何查看?

——用指令pkg-config --modversion cv_bridge查看目前系统中默认的cv_bridge版本号,pkg-config --cflags cv_bridge查看系统默认搜索cv_bridge的路径

——下面分别展示了设置系统没有调用用户自己安装的cv_bridge1.15.0(本例使用),以及默认调用了用户自己安装的cv_bridge1.15.0的截图

(2)如何修改?

在bashrc中修改:如果不source用户自己安装的cv_bridge包路径(下图中倒数第2行),那么系统默认调用cv_bridge1.13.0;

如果source用户自己安装的cv_bridge包路径(下图中倒数第2行),那么系统默认调用cv_bridge1.15.0

 

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值