ORB-SLAM2 | Prometheus_px4 | OpenCV 3.4.9

Reference to ORB-SLAM2 | GTK+ 2.x symbols detected. Using GTK+ 2.x and 3 in the same process is not supported
https://zhuanlan.zhihu.com/p/400316912

1、环境描述

操作系统:ubuntu18.04.5 LTS (AMD64)
相关软件:ORB-SLAM2、ROS-melodic(OpenCV:3.2.0 installed)、OpenCV:3.4.9(手动编译,编译时CMake添加参数:-DWITH_GTK_2_X=ON)、Prometheuse PX4 (v1)
ROS使用包(与错误相关):opencv_bridge、image_geometry
编译指令:catkin_make
注:实际这里的 ORB-SLAM 2 是经过修改且加了很多其他功能的。主要用于 prometheus_px4 中的场景仿真。

2、命令行错误信息

在屏幕上出现的如下的错误提示:

/usr/bin/ld: warning: libopencv_imgcodecs.so.3.2, needed by /opt/ros/melodic/lib/libcv_bridge.so, may conflict with libopencv_imgcodecs.so.3.4
/usr/bin/ld: warning: libopencv_core.so.3.2, needed by /opt/ros/melodic/lib/libcv_bridge.so, may conflict with libopencv_core.so.3.4
/usr/bin/ld: warning: libopencv_imgproc.so.3.4, needed by /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/libopencv_imgcodecs.so, may conflict with libopencv_imgproc.so.3.2
[  8%] Built target web_cam
[ 10%] Linking CXX shared library /home/user/Prometheus/devel/lib/libellipselib.so
[ 10%] Built target ellipselib
Makefile:159: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
[INFO] SUBMODULE object_detection_landing NOT EXIST, Skip it!
[INFO] SUBMODULE object_detection_yolov5openvino NOT EXIST, Skip it!

[ 15%] Linking CXX executable /home/user/Prometheus/devel/lib/prometheus_detection/landpad_det
/usr/bin/ld: warning: libopencv_imgcodecs.so.3.2, needed by /opt/ros/melodic/lib/libcv_bridge.so, may conflict with libopencv_imgcodecs.so.3.4
/usr/bin/ld: warning: libopencv_core.so.3.2, needed by /opt/ros/melodic/lib/libcv_bridge.so, may conflict with libopencv_core.so.3.4

3、排查过程

该问题陆续困扰我很久,简要说一下正确解决路线:

3.1、ORB-SLAM 相关问题

从提示中可猜测到,ORB-SLAM在编译过程中使用了多个不同版本的OpenCV库,因此造成了冲突。

要排查到底是具体哪些库的使用之相关,则需要引入一个查看动态库依赖的命令:

ldd  #(list dynamic dependencies)

这个命令的作用是列出程序或动态库的依赖关系。

例如:查看 libslam_semantic_nav_ros.so 库文件运行所依赖的库:

~/slam_ws/src/orbslam2/lib$ ldd libslam_semantic_nav_ros.so | grep libopencv
    libopencv_calib3d.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_calib3d.so.3.2 (0x00007fce94e1c000)
    libopencv_core.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_core.so.3.2 (0x00007fce949e1000)
    libopencv_features2d.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_features2d.so.3.2 (0x00007fce9472c000)
    libopencv_highgui.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.3.2 (0x00007fce94520000)
    libopencv_imgproc.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.3.2 (0x00007fce93fcf000)
    libopencv_video.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_video.so.3.2 (0x00007fce93d6c000)
    libopencv_text.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_text.so.3.2 (0x00007fce93a4d000)
    libopencv_core.so.3.4 => /usr/local/lib/libopencv_core.so.3.4 (0x00007fce8fef8000)					# 版本与前面的不同。
    libopencv_imgcodecs.so.3.4 => /usr/local/lib/libopencv_imgcodecs.so.3.4 (0x00007fce8fa9f000)		# 版本与前面的不同。
    libopencv_ml.so.3.4 => /usr/local/lib/libopencv_ml.so.3.4 (0x00007fce8f3e6000)
    libopencv_flann.so.3.4 => /usr/local/lib/libopencv_flann.so.3.4 (0x00007fce8d785000)
    libopencv_flann.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_flann.so.3.2 (0x00007fce8c287000)
    libopencv_imgcodecs.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2 (0x00007fce8a13f000)
    libopencv_ml.so.3.2 => /usr/lib/x86_64-linux-gnu/libopencv_ml.so.3.2 (0x00007fce896df000)
    libopencv_imgproc.so.3.4 => /usr/local/lib/libopencv_imgproc.so.3.4 (0x00007fce82950000)

上面列出的信息:
#第一列:程序需要依赖什么库
#第二列: 程序所需库在系统中的路径位置
#第三列:即括号中的数,为库加载的开始地址
#如果需要某个库,但程序在系统找不到对应的库,会出现第5行的not found信息

3.2、通过 ldd 命令排查库依赖

一般而言 Prometheus 和 ORB-SLAM2 本身用的库:

orbslam2/lib/liborbslam2.so
orbslam2/Thirdparty/DBoW2/lib/libDBoW2.so
orbslam2/Thirdparty/g2o/lib/libg2o.so
opencv、eigen3等 ORB-SLAM2 所需的库
ros 功能包的相关库等。

首先,通过使用 ldd liborbslam2.so | grep opencv 命令发现 liborbslam2.so 确实链接了 opencv-3.2.0 和 opencv-3.4.9 两个版本的库,输出如下:

~/Prometheus/devel/lib$ ldd libkcftrackerlib.so | grep opencv
	libopencv_core.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_core.so.3.4 (0x00007f6db569a000)
	libopencv_imgproc.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_imgproc.so.3.2 (0x00007f6db3e87000)
	libopencv_core.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_core.so.3.2 (0x00007f6db199d000)

继续查看 prometheus_detection 下的 stereo_detection_saving_gazebo_samples 的库依赖

~/Prometheus/devel/lib/prometheus_detection$ ldd stereo_detection_saving_gazebo_samples | grep opencv
	libopencv_core.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_core.so.3.4 (0x00007efcba027000)
	libopencv_imgcodecs.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_imgcodecs.so.3.4 (0x00007efcb96c9000)
	libopencv_highgui.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_highgui.so.3.4 (0x00007efcb88c0000)
	libopencv_imgcodecs.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_imgcodecs.so.3.2 (0x00007efcb6cb8000)
	libopencv_imgproc.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_imgproc.so.3.2 (0x00007efcb519d000)
	libopencv_core.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_core.so.3.2 (0x00007efcb42af000)
	libopencv_imgproc.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_imgproc.so.3.4 (0x00007efcb1fd5000)

再次确认一下 prometheus_detection 中 web_cam 的库依赖情况。

~/Prometheus/devel/lib/prometheus_detection$ ldd web_cam | grep opencv
	libopencv_core.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_core.so.3.4 (0x00007fb6482a3000)
	libopencv_imgproc.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_imgproc.so.3.2 (0x00007fb646a90000)
	libopencv_imgcodecs.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_imgcodecs.so.3.4 (0x00007fb646132000)
	libopencv_videoio.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_videoio.so.3.4 (0x00007fb6454e7000)
	libopencv_imgcodecs.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_imgcodecs.so.3.2 (0x00007fb6436da000)
	libopencv_core.so.3.2 => /home/npuyin/ThirdParty/OpenCV-3.2.0_install/lib/libopencv_core.so.3.2 (0x00007fb6424e4000)
	libopencv_imgproc.so.3.4 => /usr/local/opencv-3.4.9/lib/libopencv_imgproc.so.3.4 (0x00007fb63ffe0000)

3.3 、排查结果

上述排查已经基本确定了是 opencv 等库依赖出现问题。具体来源是由于 ROS 系统安装的时候自带了OpenCV 3.2.0 (lib 文件安装位置位于 /usr/lib/x86_64-linux-gnu/),而我自用的OpenCV 3.4.9 (安装在/usr/local/lib/)。在编译链接orbslam工程的时候,由于不恰当的配置造成了一部分文件引用了OpenCV 3.2.0,而一部分文件引用了OpenCV 3.4.9 。

确认位置:

$ ls /usr/lib/x86_64-linux-gnu/ | grep opencv
libopencv_aruco.a
libopencv_aruco.so
libopencv_aruco.so.3.2
libopencv_aruco.so.3.2.0
libopencv_bgsegm.a
libopencv_bgsegm.so
libopencv_bgsegm.so.3.2
libopencv_bgsegm.so.3.2.0
libopencv_bioinspired.a
libopencv_bioinspired.so
libopencv_bioinspired.so.3.2
libopencv_bioinspired.so.3.2.0
libopencv_calib3d.a
libopencv_calib3d.so
libopencv_calib3d.so.3.2
libopencv_calib3d.so.3.2.0
libopencv_ccalib.a
libopencv_ccalib.so
libopencv_ccalib.so.3.2
libopencv_ccalib.so.3.2.0
libopencv_core.a
libopencv_core.a_backup
libopencv_core.so
libopencv_core.so.3.2
libopencv_core.so.3.2.0
libopencv_core.so.3.2.0_backup
libopencv_core.so.3.4
libopencv_core.so.3.4.9
……

3.4、解决问题的思路

问题转到:查找ROS自带 OpenCV 库与 自行安装 OpenCV 冲突问题。

单纯 修改/opt/ros/melodic/share/cv_bridge/cmake下*Config.cmake文件版本库,或者更改 CmakeLists.txt 中的 find_package() 并不能完全解决问题。

cv_bridgeConfig.cmake  
cv_bridgeConfig-version.cmake  
cv_bridge-extras.cmake

编译 orbslam 工程的 CmakeLists.txt 中使用的 ROS 功能包 opencv_bridge 和 image_geometry 的库依赖了OpenCV 3.2.0

4、解决办法

参考相关文献给出的两种方法:

4.1、单独卸载这俩ROS功能包(没有验证)

适用于源码编译安装的 ROS 朋友:去 github 下载相应的包,放到 ros 工作空间的src文件夹下,配置他们的CmakeLists.txt 文件中相应的编译路径,使他们编译的时候使用自己安装的 OpenCV 3.4.15 库。

4.2、直接卸载ros自带的OpenCV(我使用的)

思路简述:
首先、卸载该 OpenCV(即3.2.0版本) 会使得所有依赖此opencv-3.2.0 的 ROS 功能包全部卸载。卸载完成后,去 github 下载工程所需要的缺失的功能包(opencv_bridge 和 image_geometry),放到 ros 工作空间的 src 文件夹下,配置他们的 CmakeLists.txt 文件,使他们编译的时候使用自己安装的 OpenCV 库。

步骤:

1、使用 dpkg --get-selections | grep opencv 指令查找所有opencv相关包
输出可能如下所示:

~$ dpkg --get-selections | grep opencv
libopencv-calib3d-dev:amd64			install
libopencv-calib3d3.2:amd64			install
libopencv-contrib-dev:amd64			install
libopencv-contrib3.2:amd64			install
libopencv-core-dev:amd64			install
libopencv-core3.2:amd64				install
libopencv-dev						install
libopencv-features2d-dev:amd64		install
libopencv-features2d3.2:amd64		install
libopencv-flann-dev:amd64			install
libopencv-flann3.2:amd64			install
libopencv-highgui-dev:amd64			install
libopencv-highgui3.2:amd64			install
libopencv-imgcodecs-dev:amd64		install
libopencv-imgcodecs3.2:amd64		install
libopencv-imgproc-dev:amd64			install
libopencv-imgproc3.2:amd64			install
libopencv-ml-dev:amd64				install
libopencv-ml3.2:amd64				install
libopencv-objdetect-dev:amd64		install
libopencv-objdetect3.2:amd64		install
libopencv-photo-dev:amd64			install
libopencv-photo3.2:amd64			install
libopencv-shape-dev:amd64			install
libopencv-shape3.2:amd64			install
libopencv-stitching-dev:amd64		install
libopencv-stitching3.2:amd64		install
libopencv-superres-dev:amd64		install
libopencv-superres3.2:amd64			install
libopencv-ts-dev:amd64				install
libopencv-video-dev:amd64			install
libopencv-video3.2:amd64			install
libopencv-videoio-dev:amd64			install
libopencv-videoio3.2:amd64			install
libopencv-videostab-dev:amd64		install
libopencv-videostab3.2:amd64		install
libopencv-viz-dev:amd64				install
libopencv-viz3.2:amd64				install
libopencv3.2-java					install
libopencv3.2-jni					install
opencv-data							install
python-opencv						install
ros-melodic-vision-opencv			install

2、从输出中看到 libopencv-core3.2:amd64 install
使用命令 sudo apt-get remove libopencv-core3.2 卸载opencv3.2.0,注意不要添加 purge 参数

3、输完指令后会出现如下类似输出

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ros-melodic-compressed-depth-image-transport ros-melodic-compressed-image-transport ros-melodic-cv-bridge ros-melodic-depth-image-proc
  ros-melodic-desktop ros-melodic-desktop-full ros-melodic-gazebo-plugins ros-melodic-gazebo-ros-pkgs ros-melodic-image-geometry
  ros-melodic-image-pipeline ros-melodic-image-proc ros-melodic-image-publisher ros-melodic-image-rotate ros-melodic-image-transport-plugins
  ros-melodic-image-view ros-melodic-perception ros-melodic-rqt-common-plugins ros-melodic-rqt-image-view ros-melodic-simulators
  ros-melodic-stereo-image-proc ros-melodic-theora-image-transport ros-melodic-vision-opencv ros-melodic-viz
0 upgraded, 0 newly installed, 5 to remove and 0 not upgraded.
After this operation, 3.8 MB disk space will be freed.
Do you want to continue? [Y/n]

卸载完成后,新开一个终端,输入 roscore,若成功运行,则基本无问题。

4、下载 ros 对应功能包
网址:https://github.com/ros-perception/vision_opencv
将 opencv_bridge 和 image_geometry ,放到 ros 工作空间的 src 文件夹下。
使用 pkg-config --modversion opencv 查看当前 OpenCV 版本,输出 3.4.9 则无问题。

~$ pkg-config --modversion opencv
3.4.9

5、后续
删除ROS工作空间之前的build和devel文件,重新编译(catkin_make)整个工程。

6、附
一些相关问题网页链接:
1 cv_bridge依赖opencv版本的问题
2 OpenCV error when trying to run ROS examples
3 OpenCV error when running ros examples in Ubuntu + ROS
4 关于解决libopencv_core.so.2.4, needed by … 的问题
5 解决Ubuntu环境下ROS 中的cv_bridge和自装OpenCV兼容性笔记
6 ubuntu下多版本opencv切換
7 ·Ubuntu 18.04 ROS-melodic 源码安装指定版本opencv 和 opencv_contrib 使用nonfree模块surf算法
8. 在Ubuntu中通过CV_bridge更改OpenCV版本
https://blog.csdn.net/weixin_48110541/article/details/125176144

7、后记

安装后,Terminal 启动时的相关提示

GAZEBO_PLUGIN_PATH :/home/user/Prometheus/devel/lib:/home/user/prometheus_px4/build/amovlab_sitl_default/build_gazebo
GAZEBO_MODEL_PATH :/home/user/Prometheus/Simulator/gazebo_simulator/models:/home/user/Prometheus/Simulator/gazebo_simulator/amov_models:/home/user/prometheus_px4/Tools/sitl_gazebo/models
LD_LIBRARY_PATH /home/user/Prometheus/devel/lib:/opt/ros/melodic/lib:/usr/local/opencv-3.4.9/lib:/usr/local/cuda-11.1/lib64:/usr/local/cuda/lib64:/home/user/prometheus_px4/build/amovlab_sitl_default/build_gazebo

可以在 /home/npuyin/prometheus_px4/Tools/setup_gazebo.bash 中注释下面三行来关闭显示!

# echo -e "GAZEBO_PLUGIN_PATH $GAZEBO_PLUGIN_PATH"
# echo -e "GAZEBO_MODEL_PATH $GAZEBO_MODEL_PATH"
# echo -e "LD_LIBRARY_PATH $LD_LIBRARY_PATH"

8、临时记录

如果有某个功能包或者软件的安装需要用新的覆盖,例如 php7.2 的相关模块重新安装。最好的办法是到:

cd /var/lib/dpkg/info
ls | grep php
sudo mkdir PHP7.2_BK
sudo mv ./php7.2* ./PHP7.2_BK
cd ~/
sudo apt install php7.2-*

即从注册表中删除该模块,然后再重新安装。

9、忠告

不要在同一个主控上安装多个版本opencv,那是自找麻烦,涉及到各种配置,配置不对就导致程序无法运行,调试配置花费大量精力!
来源:
cv_bridge与opencv版本不一致导致程序编译错误及无法运行程序问题的解决方案(附带ORB_SLAM3案例)
https://blog.csdn.net/qq_18276949/article/details/114820705

1、问题描述

换做其他开发环境遇到的问题也是类似的,解决方案也是类似的,因此本解决方案是通用的。

=================

开发环境

嵌入式主控:nvidia xavier
操作系统:ubuntu 18.04, ROS melodic
(1)ros melodic 默认安装 opencv3.2
(2)使用的 zed 相机需要在 xavier 上安装了CUDA10.0,并默认安装了opencv4.1.1
(3)系统源码安装了另一个opencv版本 opencv3.4.9
总的来说,问题中的主控 xavier 上总共有3个版本的opencv:3.2, 4.1.1, 3.4.9

=================

程序配置

主控中 ROS 节点程序因为要使用 zed 相机,对应的 cmakelists.txt 中编译用的是find_package(OpenCV 4 REQUIRED),如果用3就导致程序根本编译不通过。

这就导致用户程序调用的 opencv 库版本4.1.1与 ROS 默认安装的 cv_bridge 调用的opencv-3.2.0不一致问题!

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

===================================================

2、问题造成的后果

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

例如:
(1) 跑 ORB_SLAM2 和/或 ORB_SLAM3 失败
(2) 跑基于 opencv 库函数的用户程序失败
等等
——以下展示了ORB_SLAM3编译其ROS例程结果,只有几个节点编译成功,其他节点报出由于opencv版本冲突问题导致编译失败错误。

3、解决方案

总体思路:使用高版本的OpenCV对应的cv_bridge。例如:由于用户程序或 ORB_SLAM3 只能使用 opencv4 才能编译通过,因此解决方案只能是安装使用 opencv4 的 cv_bridge。
另外:ROS noetic 默认安装 cv_bridge1.15.0 以及 opencv-4.2.0。因此,需要下载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包一起下载下来整体编译安装
(2)注意,对应下载源码时选择

noetic ==> vision_opencv-1.15.0
melodic ==> vision_opencv-1.13.0

不同版本 opencv 的安装路径,可以在对应的 ${INSTALL_PATH}/lib/pkgconfig/opencv.pc 中查看到!

你可能感兴趣的:(环境配置,VSLAM,opencv,计算机视觉)