790 words
4 minutes
jetson ros opencv cuda compatible

ros换源#

原中科大源很多包都已经不再被维护了,使用清华源

Terminal window
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt update

opencv#

因为jetson xavier nx自带的opencv没有支持cuda,为了能够使用cuda,需要源码编译opencv4.5。

但是在我的情况下,我的ros的工作空间中有太多的文件已经依赖自带的opencv了,所以不能直接删除自带的opencv而完全替换为新的opencv4.5.4。因此需要能够同时允许系统自带opencv和支持cuda的opencv4.5.4

opencv4.5.4编译#

从opencv官网下载opencv4.5.4的源码,和对应的opencv_contribe的源码,解压。 为了不影响本来就有的opencv,在/usr/local/下自己新建一个opencv4.5.4的文件夹

Terminal window
sudo mkdir /usr/local/opencv4.5.4

进入到解压后的opencv-4.5.4文件夹中,自己新建一个build文件夹,进入其中,使用以下命令。

Terminal window
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local/opencv4.5.4 \
-DOPENCV_ENABLE_NONFREE=1 \
-DBUILD_opencv_python2=1 \
-DBUILD_opencv_python3=1 \
-DWITH_FFMPEG=1 \
-DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda \
-DCUDA_ARCH_BIN=7.2 \
-DCUDA_ARCH_PTX=7.2 \
-DWITH_CUDA=1 \
-DENABLE_FAST_MATH=1 \
-DCUDA_FAST_MATH=1 \
-DWITH_CUBLAS=1 \
-DOPENCV_GENERATE_PKGCONFIG=1 \
-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.5.4/modules \
..

其中,CMAKE_INSTALL_PREFIX就是希望把opencv按转到的目标路径,OPENCV_EXTRA_MODULES_PATH是对应的opencv_contrib中的module文件夹的相对路径。

cmake成功后,就可以make了。

因为是在jetson板子上进行编译,所以需要的时间可能会非常长,又不想费精力去弄交叉编译了,所以要尽可能的利用多核,在我这里我使用make -j6因为nx有6个CPU核心,同时开了一个tmux窗口,这样可以防止不小心把make给挂了。

make结束后还需要sudo make install,把一些相关的库放到/usr等系统目录下。

对应cv_bridge的处理#

melodic自带的cv_bridge和opencv4.5会有冲突,所以如果希望使用opencv4.5,需要自己在工作空间下下载源码vision_opencv,然后使用工作空间内的cv_bridge。

为了能够使用opencv4.5,需要下载noetic 版本的vision_opencv,并且修改vision_opencv/cv_bridge下的CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(cv_bridge)
set(OpenCV_DIR "/usr/loca/opencv4.5.4") # 此处OpenCV_DIR修改为自己安装的opencv的路径
find_package(catkin REQUIRED COMPONENTS rosconsole sensor_msgs)
if(NOT ANDROID)
find_package(PythonLibs)
if(PYTHONLIBS_VERSION_STRING VERSION_LESS "3.8")
# Debian Buster
find_package(Boost REQUIRED python3)
else()
# Ubuntu Focal
find_package(Boost REQUIRED python)
endif()
else()
find_package(Boost REQUIRED)
endif()
set(_opencv_version 4)
find_package(OpenCV 4.5.4 QUIET) # 为了明确指定希望使用的opencv的版本
if(NOT OpenCV_FOUND)
message(STATUS "Did not find OpenCV 4, trying OpenCV 3")
set(_opencv_version 3)
endif()

但是仅仅修改以后,cmake虽然可以了,但是在编译的时候仍然会遇到报错“ /home/nvidia/zal_ws/src/vision_opencv/cv_bridge/src/module.hpp: In function ‘void* do_numpy_import()’: /usr/include/python2.7/numpy/__multiarray_api.h:1537:144: error: return-statement with no value, in function returning ‘void*’ [-fpermissive] #define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, “numpy.core.multiarray failed to import”); return NUMPY_IMPORT_ARRAY_RETVAL; } } ”

根据报错信息,直接去修改源码:

进入/vision_opencv/cv_bridge/src/module.hpp,把do_numpy_import函数的声明修改为

static void do_numpy_import( )
{
import_array( );
}

再次catkin_make,成功编译。

在工作空间中指定需要的cv_bridge和opencv#

在自己的CMakeLists.txt中明确指定需要的opencv版本,cv_bridge不需要专门指定,catkin_make的时候会优先使用工作空间内的cv_bridge的源码编译生成的包的。

set(OpenCV_DIR "/usr/local/opencv4.5.4") # Opencv的安装路径
find_package(OpenCV 4.5.4 REQUIRED)
find_package(catkin REQUIRED COMPONENTS
cv_bridge
... # 其它需要的包
)

接下来,在代码中,就可以正常的导入opencv4.5cv_bridge了。

jetson ros opencv cuda compatible
https://blog.cassiusblack.top/posts/jetson-ros-opencv-yolo/
Author
Cassius Black
Published at
2024-06-09
License
CC BY-NC-SA 4.0