Cyan Infinite - Compiling ROS cv_bridge with Python 3
Compiling ROS cv_bridge with Python 3
Wanted to compile ROS packages with Python 3 on ROS Melodic, only realizing that catkin_make only compiles Python 2 scripts instead after a while? No worries! In this tutorial, we’ll be looking exactly into that.
Contents
Since ROS does not support Python 3 by default, we would have to compile cv_bridge via another method if want to use OpenCV 4 with Python 3.
Fun fact: ROS2 supports Python 3 by default.
Furthermore, as the support of Python 2.7 ended last year (December 2019), it is recommended to discontinue the use of Python 2.7 as it would not be updated anymore and move on to Python 3.
Therefore, this tutorial would be covering how to compile a Python 3 ROS package with ROS Melodic, specifically cv_bridge
. With that, let’s get started!
Dependencies
We’ll first download the python build tools:
$ sudo apt-get install python3-pip python-catkin-tools python3-dev python3-numpy $ sudo pip3 install rospkg catkin_pkg
Workspace
Next, create a separate workspace to compile the bridge_cv
ROS package. We would be naming the directory cvbridge_build_ws
.
$ mkdir -p ~/cvbridge_build_ws/src $ cd ~/cvbridge_build_ws/src
After the workspace has been setup, we’ll clone the open_vision repository into ~/cvbridge_build_ws/src
:
$ git clone -b noetic https://github.com/ros-perception/vision_opencv.git
We would be downloading the noetic branch
instead of the melodic branch
as it supports for both OpenCV 4 and Python 3.If you try compiling immediately, you would get this error:
Therefore, we need to make a slight change to the cv_bridge
CMakeLists.txt
file before proceeding as Ubuntu 18.04 is not be able to recognise python37 by default.
Open CMakeLists.txt
with you favorite text editor and make the following modification at Line 11, changing:
find_package(Boost REQUIRED python37)
to
find_package(Boost REQUIRED python3)
Save and exit the text editor.
Compilation
After the dependencies and workspace have been setup, we would proceed to configure the workspace for compilation:
$ cd ~/cvbridge_build_ws$ catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.6m -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libpython3.6m.so这里未用到$ catkin config -DPYTHON_EXECUTABLE=/home/kevalen/miniconda3/bin/python3 -DPYTHON_INCLUDE_DIR=/home/kevalen/miniconda3/include/python3.9 -DPYTHON_LIBRARY=/home/kevalen/miniconda3/lib/python3.9/site-packages $ catkin config --install
I just wanted to add that if you are using Ubuntu the DPYTHON_LIBRARY flag should begin with
/usr/lib/x86_64-linux-gnu/…
Note: Change the python path accordingly, you could check out the location via Python 3.
$ python3 >>> import sys >>> print(sys.executable) #Print python3 executable path >>> print(sys.path) #Print python3 library path >>> quit()To find where the include files are:
$ python3-config --includes
After the configuration is completed, build the package:
$ catkin build cv_bridge -DSETUPTOOLS_DEB_LAYOUT=OFF
上面添加-DSETUPTOOLS_DEB_LAYOUT=OFF 的原因是解决error: option --install-layout not recognized 。参见连接Building catkin Workspace fails - install-layout not recognized · Issue #863 · ros/catkin · GitHub
To use the package, you could source it via:
$ source install/setup.bash --extend
And Viola! You have “compiled” the cv_bridge package via Python 3.
You could add it to .bashrc if you use the ROS package frequently.
References
- https://wiki.ros.org/UsingPython3
- https://medium.com/@beta_b0t/how-to-setup-ros-with-python-3-44a69ca36674
- https://answers.ros.org/question/350904/cv_bridge-throws-boost-import-error-in-python-3-and-ros-melodic/
- https://stackoverflow.com/questions/49221565/unable-to-use-cv-bridge-with-ros-kinetic-and-python3
- https://stackoverflow.com/questions/35071192/how-to-find-out-where-the-python-include-directory-is
- https://stackoverflow.com/questions/6767283/find-where-python-is-installed-if-it-isnt-default-dir#6767329
终极解决方案:
YOLOV4_Deepsort_ROS/track_deep.py at main · leicheng5/YOLOV4_Deepsort_ROS · GitHub
"""
Provides conversions between OpenCV and ROS image formats in a hard-coded way.
CV_Bridge, the module usually responsible for doing this, is not compatible with Python 3,
- the language this all is written in. So we create this module, and all is... well, all is not well,
- but all works. :-/
"""
import sys
import numpy as np
from sensor_msgs.msg import Image
def imgmsg_to_cv2(img_msg):
if img_msg.encoding != "bgr8":
rospy.logerr("This Coral detect node has been hardcoded to the 'bgr8' encoding. Come change the code if you're actually trying to implement a new camera")
dtype = np.dtype("uint8") # Hardcode to 8 bits...
dtype = dtype.newbyteorder('>' if img_msg.is_bigendian else '<')
image_opencv = np.ndarray(shape=(img_msg.height, img_msg.width, 3), # and three channels of data. Since OpenCV works with bgr natively, we don't need to reorder the channels.
dtype=dtype, buffer=img_msg.data)
# If the byt order is different between the message and the system.
if img_msg.is_bigendian == (sys.byteorder == 'little'):
image_opencv = image_opencv.byteswap().newbyteorder()
return image_opencv
def cv2_to_imgmsg(cv_image):
img_msg = Image()
img_msg.height = cv_image.shape[0]
img_msg.width = cv_image.shape[1]
img_msg.encoding = "bgr8"
img_msg.is_bigendian = 0
img_msg.data = cv_image.tostring()
img_msg.step = len(img_msg.data) // img_msg.height # That double line is actually integer division, not a comment
return img_msg
https://github.com/Leonardo-Blanger/detr_tensorflow/issues/3