ros功能包所用opencv版本与ros默认opencv版本不一致情况解决方法

129 篇文章 12 订阅
9 篇文章 0 订阅

ros功能包所用opencv版本与ros默认opencv版本不一致情况解决方法

这种情况包含比如:
在ubuntu20.04 ros noetic opencv4的环境下部署opencv3的功能包
在ubuntu20.04 ros foxy opencv4的环境下部署opencv3.4.1的功能包(比如部署ros2的vins-fusion-gpu时)
在ubuntu18.04 ros melodic opencv3.3.1的环境下部署opencv3.4.1的功能包(比如部署vins-fusion-gpu时)

解决的关键是使得功能包所调用的cv_bridge功能包是寻找链接的我们想指定的opencv版本,由于ROS功能包一般都是默认用的装ROS时自动二进制安装的cv_bridge功能包,导致默认情况下,ROS功能包就都是使用的同一个版本的opencv,也就是这个二进制安装的cv_bridge功能包所原本找到并链接的opencv,如果我们有功能包需要使用特定版本的opencv,没法使用ros现在默认链接的opencv,此时功能包编译运行便会出现问题,比如opencv4的环境下想用opencv3的功能包,或者opencv3.3.1的环境下想用只能适配于opencv3.4.1的vinsfusiongpu,解决办法就是自己源码编译安装一个cv_bridge(如果是ROS2注意源码编译安装ROS2版本的cv_bridge),使得此cv_bridge使用我们指定版本的opencv,同时使我们的功能包使用我们源码编译安装的这个cv_bridge,就可以实现功能包找到并编译链接的我们指定版本的opencv了。

这里以在ubuntu20.04 opencv4的环境下部署原本依赖opencv3.3.1的功能包为例

首先源码编译安装opencv3.3.1和opencv_contrib3.3.1,这里假设功能包也需要opencv_contrib。
新建一个文件夹opencv331来专门存放opencv3.3.1和opencv_contrib3.3.1

mkdir opencv331
cd opencv331

然后运行下面命令下载opencv3.3.1和opencv_contrib3.3.1

git clone -b 3.3.1 https://github.com/opencv/opencv.git
git clone -b 3.3.1 https://github.com/opencv/opencv_contrib

接着编译安装
下面camke命令中,CMAKE_INSTALL_PREFIX指定了安装路径,OPENCV_EXTRA_MODULES_PATH指定了opencv_contrib的路径,注意确保opencv_contrib和opencv处于同一个文件夹内,下面OPENCV_EXTRA_MODULES_PATH指定的相对路径才有效。

cd opencv
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D WITH_CUDA=OFF -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
make -j8
sudo make install

此时ubuntu环境里面可以找到opencv4也可以找到opencv3

查找opencv3版本命令可以用

pkg-config --modversion opencv

查找opencv4版本命令可以用

pkg-config --modversion opencv4

此时单纯地把功能包的cmakelists里面的find_package(OpenCV REQUIRED)改为find_package(OpenCV 3.3.1 REQUIRED)是不够的,这样虽然可以找到opencv3.3.1,但是编译链接时会依旧链接的opencv4的库文件,因为ubuntu20.04上ros noetic二进制安装的cv_bridge默认链接的是opencv4,这样编译一般会出现譬如undefined reference to cv::mat::mat()一类带有undefined的报错,出现这种undefined的报错一般是因为找到了头文件,但是链接库的时候没有链接库或者没有找到库导致的,因为头文件一般只有函数的声明,库文件才带有函数的定义实现。

输入图片说明

可以cmakelists里面加上这些打印,会发现虽然找到的是opencv3.3.1,但是链接的库还是opencv4的

message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
message(STATUS "    catkin libraries: ${catkin_LIBRARIES}")

输入图片说明

此时需要自己再另外编码编译安装一个cv_bridge,之前系统二进制安装的cv_bridge不用卸载,只需要保证自己的功能包找到的cv_bridge功能包是源码编译安装的cv_bridge功能包即可。实现这个的操作就是自己功能包的cmakelists里面加上set(cv_bridge_DIR "your-path/cv_bridge_ws/devel/share/cv_bridge/cmake")

按照下面操作源码编译部署一个cv_bridge,使得这个cv_bridge是调用的opencv3.3.1,同时自己这个功能包是找到的这个源码编译的cv_bridge,而不是系统二进制安装的cv_bridge就可以了。

ros1下源码编译安装cv_bridge

mkdir -p cv_bridge_ws/src
cd cv_bridge_ws/src
git clone https://gitee.com/maxibooksiyi/cv_bridge
cd ..

将opencv编译生成的build文件路径加入到cv_bridge功能包的CMakeLists.txt里,命令如下,像上面自己编译安装的opecv3.3.1的build文件夹路径就是~/opencv331/opencv/build

set(OpenCV_DIR "your-path/opencv-x.x.x/build")

编译

catkin_make

如果是ros2,则源码编译安装cv_bridge功能包的步骤是

mkdir cv_bridge_ros2_ws/src
cd cv_bridge_ros2_ws
cd src
git clone https://github.com/ros-perception/vision_opencv.git -b foxy

把cv_bridge功能包里的cmakelists(/cv_bridge_ros2_ws/src/vision_opencv/cv_bridge/CMakeLists.txt)里这里的OpenCV 4改为OpenCV 3
 

输入图片说明

输入图片说明


改完后保存编译

cd ..
colcon build

源码编译部署完cv_bridge功能包之后,最后将依赖使用指定opencv版本的功能包里的CMakeLists.txt文件按照下面命令添加opencv路径以及cv_bridge路径,位置放在OpenCV和cv_bridge的find_package之前即可,这样再编译这个功能包就会链接的是所指定版本的opencv,而不是原来ros默认链接的opencv了。

set(OpenCV_DIR "your-path/opencv-x.x.x/build")
set(cv_bridge_DIR "your-path/cv_bridge_ws/devel/share/cv_bridge/cmake")
  • 35
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值