ros kinetic 自带opencv3 与 opencv 2 的兼容问题_原野寻踪的博客-程序员宅基地

技术标签: 实践经验  

问题分析

自己写的系统必须基于opencv 2.x,而ros kinetic自带了opencv3的版本。于是在编译时报错:

/usr/bin/ld: CMakeFiles/xxxx.cpp.o: undefined reference to symbol '_ZN2cv6String10deallocateEv'
/opt/ros/kinetic/lib/x86_64-linux-gnu/libopencv_core3.so.3.3.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
CMakeFiles/xxxx/build.make:192: recipe for target '../xxxx' failed

而自己的系统里 Pangolin 等一堆库都基于2.x版本opencv了,不好再做调整,于是只好强行调整ros的opencv依赖来使其适应我的系统了。

ros中用到opencv的地方是从话题中读取图像,如 /camera/image_raw话题中抓取 rgb或depth图像保存为cv::Mat,所需用到的ros包是cv_bridge。

因此核心问题是: ros的包cv_bridge使用默认opencv3编译,而自身系统使用opencv 2.x编译,opencv的混合编译带来了错误。

 

问题解决方法

方法一共有两种:

1) 浅依赖可以直接调整cv_bridge的cmake文件,详细可参考:https://www.mobibrw.com/2017/8718

这个方法可以帮助我通过编译,然而实际运行时会报内存错误。因此放弃选择第二个方式,各位如果想省时间也可以试试这个方式,只需要改文件的几行路径。

注意: 改完cv_bridge的cmake文件后,一定要 rm -rf build 文件然后重新 cmake .. & make 才会生效。

 

2)重度依赖,一劳永逸

直接将cv_bridge卸载掉,然后从源代码重新编译,详细参考:https://blog.csdn.net/xiat5/article/details/79354573

下面是我的执行过程。
 

步骤

使用opencv 2.x版本重新编译  cv_bridge。

1、 卸载 cv_bridge

使用指令卸载cv_bridge,

$ sudo apt-get remove --purge ros-kinetic-cv-bridge

这里会出现提示说下列包会被一并卸载,不用慌,直接y卸载,实测不影响ros 通信等基本功能的使用 [ 这里有一点提一下,可见文章最后 ]:

ros-kinetic-camera-calibration ros-kinetic-compressed-depth-image-transport
  ros-kinetic-compressed-image-transport ros-kinetic-cv-bridge ros-kinetic-depth-image-proc ros-kinetic-desktop
  ros-kinetic-desktop-full ros-kinetic-gazebo-plugins ros-kinetic-gazebo-ros-pkgs ros-kinetic-image-pipeline
  ros-kinetic-image-proc ros-kinetic-image-publisher ros-kinetic-image-rotate ros-kinetic-image-transport-plugins
  ros-kinetic-image-view ros-kinetic-perception ros-kinetic-rgbd-launch ros-kinetic-rqt-common-plugins
  ros-kinetic-rqt-image-view ros-kinetic-simulators ros-kinetic-stereo-image-proc
  ros-kinetic-theora-image-transport ros-kinetic-vision-opencv ros-kinetic-viz

 

2、 到github上clone 下来cv_bridge

gihub地址为:  https://github.com/ros-perception/vision_opencv

切换kinetic版本: 

$ git checkout kinetic

 

3、 修改CMakeLists.txt文件指定为你自己的opencv版本.

拿我的为例子,我的opencv 2.4.11的build路径为:  ~/opencv_2.4.11/build

于是我在 find_package(OpenCV)前加入一行::

set( OpenCV_DIR "~/opencv_2.4.11/build" )

建议可以使用message输出一下opencv version或 opencv_include 目录来确保cmake加载的自己版本的opencv.

 

3、最后

$ cmake ..  && make

$ sudo make install

出现下列情况表示安装成功

...

-- Set runtime path of "/usr/local/lib/libcv_bridge.so" to ""
-- Installing: /usr/local/lib/python2.7/dist-packages/cv_bridge/boost/cv_bridge_boost.so
-- Set runtime path of "/usr/local/lib/python2.7/dist-packages/cv_bridge/boost/cv_bridge_boost.so" to ""

 

4、回到自己最初需要用ros的代码里,对CMakeLists.txt中做一些调整:

set(cv_bridge_DIR /usr/local/share/cv_bridge/cmake)

find_package(cv_bridge)

include_directories(${cv_bridge_DIR})

target_link_libraries中将cv_bridge的库文件链接上

   ${cv_bridge_LIBRARIES}

然后按顺序编译,大功告成!!!!

 

其他

1、so文件来源

一开始我检查自己的CMakeLists.txt中,所有 target_link_libraries 的地方都没找到opencv 3.x的引用,后来梳理了ros的性质,

rosbuild_add_executable() 指令会从 manifest.xml 中读取包,而我的manifest.xml中包含了 cv_bridge

而cv_bridge自带的 cmake文件中加载了 3.x的so文件.

2、 关于ros自带包在CMakeLists.txt中的结构

这个过程其实是把 cv_bridge 当成了一个普通的库来使用的。

而ros有一套体系来让这些很简便, 如 catkin components中直接加入 cv_bridge,其实底层和这个过程是一样的。

所以这里弄明白了,ros的底层依赖关系也差不多可以自己diy了。

4、关于删除 cv_bridge 后的影响

这里卸载cv_bridge后发生了ros gazebo不发布话题的问题,其实仔细一想自带的cv_bridge可以留着,然后通过在CMakeLists.txt中指定 cv_bridge_DIR的方式来选择性调用cv_bridge版本。

5、 两个版本的安装路径

opencv 2.4.11 检查安装路径为:  /usr/local

ros-kinetic安装了opencv3, 检查安装路径为:

lib: /opt/ros/kinetic/lib/x86_64-linux-gnu

include: /opt/ros/kinetic/include/opencv-3.3.1-dev

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Crazydogg/article/details/103531561

智能推荐

MySQL||数据库查询操作(一)基本查询与基本操作_Jock.Liu的博客-程序员宅基地

建立范例数据 为了方便执行操作,我们需要建立一个范例表进行操作,如我们建立一张员工表,表中包含员工的编号,姓名,职务,入职时间,当月收入(美金),当月奖金,系属部门等。代码如下:-- 删除数据表 DROP TABLE IF EXISTS emp ; DROP TABLE IF EXISTS dept; DROP TABLE IF EXISTS salgr...

python3之文件操作_墨雨依旧付疏狂Q的博客-程序员宅基地

import osimport shutilimport time# 格式化时间def formatTime(longtime): return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(longtime))# 获取文件大小,结果保留两位小数,单位MBdef get_file_size(path): f = ...

asp.net core如何在SignalR中获取用户信息_༺举个栗子吧༻的博客-程序员宅基地_signalr user

asp.net core如何在SignalR中获取用户信息(AbpSession)业务需要在signalR中需要根据User.Id去做数据的过滤,net core在TokenAuthController中集成了登录的功能。但是登录之后,连接signalR,在signalR中直接使用AbpSession.UserId获取到的是null。一直在百度谷歌中查找,结果应该和大家一样,解决方案都是在客户端连接时传递UserId参数,在服务端连接成功的事件OnConnected中将connectionId和userI

发现Java核心技术第七版中文一处严重翻译错误_霜之哀伤的博客-程序员宅基地

Java2核心技术第七版中文版第二卷第600页,警告处这样说: 如果将jar放入jre/lib/ext目录中,并且在它的类中有一个类需要调用系统类或者扩展类,那么就会遇到麻烦。扩展类加载器并不使用类路径。 刚读到这里十分不解,为什么用到系统类或扩展类会发生错误?并且一个类怎么可能不会用到系统类?于是,找到英文版原文如下:You can run into grief if y

数据存储机制之文件存储_siqi_qiu的博客-程序员宅基地_文件存储数据

今天我们来学习下文件存储。文件存储算是Android中最为基础的一种数据存储方式了。它比较适合用于存储一些简单的文本数据后二进制数据。那么我们就先来看下Android是如何通过文件来保存数据的将数据存储到文件中首先,我们需要创建一个新的项目,并修改activity_main.xml文件。我就直接上代码了,毕竟挺简单的。<LinearLayout xmlns:android="http...

来自西弗吉利亚大学li xin整理的CV代码合集_沈子恒的博客-程序员宅基地

Reproducible Research in Computational Science “It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong” - Richard Fe

随便推点

蚁群算法原理以及应用_「已注销」的博客-程序员宅基地_蚁群算法原理及其应用

蚁群算法是一种群体智能仿生启发式算法,从提出至今已在不同领域的优化问题中已经得到广泛的应用。本文首先对启发式算法和蚁群算法的由来以及含义做简要介绍,然后讲述蚁群算法的求解原理,再分别用两个案例解释蚁群算法,观察蚁群算法的求解结果;通过对蚁群算法的使用方法做简要介绍,可以了解近似解的含义以及正反馈的作用,最后针对目前蚁群算法的发展现状和应用领域对未来的发展提出展望和目标。

ImageView设置了match_parent无法充满父布局解决方案_Paranoidyang的博客-程序员宅基地

ImageView设置如下:<ImageView android:layout_width="match_parent" android:layout_height="90dp" android:src="@drawable/game_card_gray"/>却发现图片宽度怎么也填充不满,刚开始还以为是哪里设置了padding,排查后却没有,最后搜索一

适用于Windows*操作系统的英特尔MPI库参考手册:4_haimianjie2012的博客-程序员宅基地_intel mpi共享内存

4.调试参考“英特尔MPI库”提供了一个自动调整实用程序和许多环境变量,可用于在运行时影响程序行为和性能。4.1使用mpitune实用程序mpitune使用mpitune实用程序查找与群集配置或应用程序相关的英特尔MPI库的最佳设置。语法:参数:不推荐的选项:描述:使用mpitune实用程序创建一组英特尔MPI库配置文件,其中包含特定群集或应用程序的最佳设置。通过使用-tune选项,可以在mpiexec作业启动器中重用这些配置文件。如果存在以前mpitune会话中的配置文

POI使用:用poi接口不区分xls/xlsx格式解析Excel文档(41种日期格式解析方法,5种公式结果类型解析方法,3种常用数值类型精度控制办法)_eguid_1的博客-程序员宅基地

一、使用poi解析excel文档注:全部采用poi接口进行解析,不需要区分xls、xlsx格式,不需要判断文档类型。poi中的日期格式判断仅支持欧美日期习惯,对国内的日期格式并不支持判断,怎么办?所以通过日期格式判断是极其重要的手段,因为日期在excel中也是double类型的数值,所以靠类型判断是极不可靠的,但是有几种常用的日期格式(比如:yyyy-mm-dd,yy-mm-dd等)还是可

推荐文章

热门文章

相关标签