5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片

Ubuntu18.04自带的python3.6下使用cv_bridge

  • 我自己为什么不想用Ubuntu16.04的ROS kinetic版本
  • 一、什么是cv_bridge
    • 1.cv_bridge官方文档
    • 2.调用方法
  • 二、往已有的功能包里添加所需要的依赖包(这一步出现了问题,可以直接跳过)
    • 1.要添加的包
    • 2.修改相应的配置文件
    • 3.运行图像转换脚本
    • 4.报错
  • 三、重新在python3.6的环境下编译cv_bridge
    • 1.修改配置文件(如果没有看【二】,可以跳过这一小步)
    • 2.重新修改配置文件
    • 3.从官网下载cv_bridge的源码并用python3.6编译
    • 补充
    • 4.调用用python3.6编译好的cv_bridge
  • 四、在ROS中用python3.6调用opencv
    • 1.这些之前在ROS kinetic上遇到的一些问题(废话可跳过:)
    • 2.直接在脚本中导入cv2
  • 五、在之前的调用cv_bridge的脚本中同时使用cv2

我自己为什么不想用Ubuntu16.04的ROS kinetic版本

  • 因为Ubuntu16.4自带的python3版本是3.5。因为我在开发过程中需要torch==1.6.0,需要python3.6+的环境,Ubuntu18.04自带的python3.6会舒服很多。
  • 但是仍然可以把Ubuntu16.04的python3.5升级为python3.7,然后使用更高版本的包,通过升级得到的python3.7会出现很多问题。百度上这样的教程有很多,我可能会总结一下发一篇博客:)P
  • 建议升级Ubuntu18.04系统,安装melodic版本的ROS,kinetic和melodic没有什么太大的区别,可以兼容kinetic。

一、什么是cv_bridge

1.cv_bridge官方文档

cv_bridge的官方教程。
http://wiki.ros.org/cv_bridge/Tutorials/ConvertingBetweenROSImagesAndOpenCVImagesPython

  • cv_bridge是一个将ROS图像(sensor_msgs/Image)转换为OpenCV图像,并将OpenCV图像转换为ROS和OpenCV的接口。

2.调用方法

from cv_bridge import CvBridge
bridge = CvBridge()
# opencv图像转换为sensor_msgs/Image图像
image_message = bridge.cv2_to_imgmsg(cv_image, encoding="bgr8")
# 把sensor_msgs/Image图像转换为opencv图像
cv_image = bridge.imgmsg_to_cv2(image_message, desired_encoding='bgr8')

二、往已有的功能包里添加所需要的依赖包(这一步出现了问题,可以直接跳过)

1.要添加的包

  1. sensor_msgs
  2. opencv2
  3. cv_bridge

2.修改相应的配置文件

  1. 进入当前功能包(my_pkg功能包为例)的目录下,打开package.xml文件。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第1张图片
  2. 添加如下配置。(和上面格式一样)
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第2张图片
  3. 打开CMakeLists.txt文件。添加如下的配置:
  • 5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第3张图片
  • 5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第4张图片
  1. 重新编译当前工作空间cd ../../ && catkin_make
    编译的时候报错,提示找不到opencv的CMakeLists.txt文件,然后我把opencv2从上面的配置文件中删除,重新编译成功。

3.运行图像转换脚本

  1. 运行rosrun my_pkg imgmsg_to_cv2.py,然后开启一个发布sensor_msgs/Image消息的topic,这里我自己录了一个包,里面有摄像头发布这个数据的topic,所以直接用rosbag play xxx.bag发布消息。
#!/usr/bin/python3
#-*- coding:UTF-8 -*-

import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge

def ConvertCallback(msg):
    bridge = CvBridge()
    # 把ROS图像转换为opencv图像
    cvimg = bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8')
    rospy.loginfo("Convert image_message to cv2_img successfully.")

def cameralane_subcriber():
    # ROS节点初始化
    rospy.init_node('convert_subcriber', anonymous=True)

    # 创建一个Subcriber,订阅一个发布sensor_msgs/Image的topic,注册回调函数 ConvertCallback()
    rospy.Subscriber("/xxx/topic", Image, ConvertCallback)

    # 循环等待回调函数
    rospy.spin()


if __name__ == '__main__':
    cameralane_subcriber()

4.报错

  1. 报错。

ImportError: dynamic module does not define module export function (PyInit_cv_bridge_boost)

5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第5张图片

三、重新在python3.6的环境下编译cv_bridge

1.修改配置文件(如果没有看【二】,可以跳过这一小步)

  • 把相应的cv_bridge从上面的配置文件中删除。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第6张图片
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第7张图片
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第8张图片

2.重新修改配置文件

  1. 参考【二】中的第2小步,把sensor_msgs这个包添加到package.xml和CMakeLists.txt中。
  2. 重新编译工作空间catkin_make
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第9张图片

3.从官网下载cv_bridge的源码并用python3.6编译

用python3.6编译源码的全部过程参考这个链接(这个链接是在kinetic版本下用python3.5编译的):https://stackoverflow.com/questions/49221565/unable-to-use-cv-bridge-with-ros-kinetic-and-python3?rq=1

  1. sudo apt-get install python-catkin-tools python3-dev python3-catkin-pkg-modules python3-numpy python3-yaml ros-melodic-cv-bridge安装一些相关的依赖包。
  2. cd ~ && mkdir cv_bridge_ws在用户根目录下创建新的cv_bridge的工作空间。
  3. cd cv_bridge_ws && catkin init初始化工作空间,这一步会出现一些红色的提示,不用管。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第10张图片
  4. catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.6m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.6m.so设置cmake编译选项。
  5. catkin config --install把所有编译好的包放在工作空间的install文件夹下(暂时没有该文件夹,不用管)。
  6. git clone https://github.com/ros-perception/vision_opencv.git src/vision_opencv把源码克隆到工作空间的src目录下
  7. apt-cache show ros-melodic-cv-bridge | grep Version在本地仓库中找cv_bridge的版本。
    在这里插入图片描述
  8. cd src/vision_opencv/ && git checkout 1.13.0
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第11张图片
  9. cd ../../ && catkin build cv_bridge编译cv_bridge,按照上面的步骤来的话,应该不会有Error出现,如果出现了,可以自行百度:(
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第12张图片
  10. source install/setup.bash --extend把当前的功能包(vision_opencv)扩展到环境中?然后其他的功能包就可以使用了。不想每次打开终端都要source一下,可以把source命令写进~/.bashrc文件中。sudo gedit ~/.bashrc
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第13张图片

补充

  1. 如果遇到下面的这个问题:
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第14张图片
  • 原因是:cmake要找到libboost_python3.so这个库,但是在Ubuntu16.04中这个库叫libboost_python-py35.so这个名字路径是(/usr/lib/x86_64-linux-gnu/libboost_python-py35.so)。要把src/vision_opencv/cv_bridge/CMakeLists.txt中的find_package(Boost REQUIRED python3)改为find_package(Boost REQUIRED python-py35)然后重新编译工作空间。
  • 这个是在kinetic版本中出现的,在melodic版本中没有出现这个问题。
  1. (在不同环境下,比如说kinetic和Xavier)在自己的脚本中调用cv_bridge的时候,from cv_bridge import getType(好像是这个),会出现报错。只需要把~/cv_bridge_ws/src/vision_opencv/cv_bridge这个文件夹复制到自己脚本所在的目录问题就可以解决了。

4.调用用python3.6编译好的cv_bridge

  1. roscore
  2. rosrun my_pkg imgmsg_to_cv2.py启动在【二】(3)编写好的图像转换脚本。
  3. rosbag play xxx.bag重现有sensor_msgs/Image消息的bag包。
  4. 运行成功。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第15张图片

四、在ROS中用python3.6调用opencv

1.这些之前在ROS kinetic上遇到的一些问题(废话可跳过:)

  1. 之前用Ubuntu16.04中ROS的kinetic的版本的时候,调用opencv的时候出现了很多问题。原因是ROS默认使用pyhton2.7,但是当脚本中指定运行环境为python3的时候,
  • /opt/ros/kinetic/lib/python2.7/dist-packages 路径下的opencv找不到cv.2so还是cv.so(具体的忘记了)。

  • 百度上有许多类似这样的解决方法。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第16张图片

  • 但是现在,只要在python3下安装opencv就可以了,pip3 install opencv-python==3.4.3.18。(之前在ROS kinetic上就不行,可能只是我个人的问题:)

  1. 因为遇到上面这些问题的时候,是在我刚学ROS的时候,遇到的所有问题,都只有查博客。在不断的查资料的过程中,我得到了很多经验,现在把这些经验记录一下。(因为项目需要python3.6+的环境,而ROS Kinetic只有原生的python3.5,在我一顿操作把它升级到python3.7之后,出现了一些我暂时解决不了的问题,然后被迫重新安装有原生python3.6的ROS Melodic。又是从头开始查资料,幸好之前把整个过程都自己跑了一下,所以新版本的安装异常顺利。

2.直接在脚本中导入cv2

  • rosrun my_pkg cv2_test.py记得设置py脚本的可执行权限。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第17张图片
  • vscode中有个很头疼的问题,好像不支持系统的相对路径?vscode代码中的根目录好像是当前的工作空间?建议直接使用绝对路径!
  • 脚本如下
#!/usr/bin/python3
#-*- coding:UTF-8 -*-
import cv2

if __name__ =="__main__":
    img = cv2.imread('/home/mkid/ros_bag/srcimg.jpg')
    cv2.imshow('img', img)

    #cv2.imwrite('~/ros_bag/convert.jpg', img)
    cv2.imwrite('/home/mkid/ros_bag/convert.jpg', img)
    print('yes')

五、在之前的调用cv_bridge的脚本中同时使用cv2

  • 和【四】(2)一样,只要在bridge.imgmsg_to_cv2函数下调用cv2相关的函数就行。
  • 之前的脚本在【二】(3)中。
    5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第18张图片

5.ROS(melodic版本)在python3.6下用cv_bridge把sensor_msgs/Image消息转换为opencv格式的图片_第19张图片

你可能感兴趣的:(ROS系统,python,opencv,linux)