本地是Ubuntu22.04系统,安装了ROS2-humble,看了下humble自带的OpenCV版本4.5.4,由于DNN模块读取.onnx格式的模型要用OpenCV4.7及以上的版本,于是编译了4.10.0的OpenCV,但开发ROS2节点时,虽然CMake中已经指定了OpenCV的依赖路径,但还是会依赖系统中自带的OpenCV版本。
1.准备OpenCV-4.10.0依赖库
-
下载官方源码进行编译,参考:https://blog.youkuaiyun.com/qq_45445740/article/details/144244604
-
也可以直接下载编译好的包:
https://download.youkuaiyun.com/download/qq_45445740/90134597
2.源码参考
- CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(
my_test
LANGUAGES CXX C
DESCRIPTION "my_node_test")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# 设置ROS2版本
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(cv_bridge REQUIRED)
set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/opencv-4.10.0/lib/cmake/opencv4" ${CMAKE_PREFIX_PATH})
find_package(OpenCV 4.10.0 REQUIRED COMPONENTS)
message("opencv path: ${CMAKE_PREFIX_PATH}")
message("opencv version: ${OpenCV_VERSION}")
message("opencv include dir: ${OpenCV_INCLUDE_DIRS}")
message("opencv libraries: ${OpenCV_LIBS}")
# 设置头文件路径并添加到目标
add_executable(my_node
src/my_node.cpp)
# 设置 OpenCV 的头文件目录
target_include_directories(my_node PRIVATE
include
${OpenCV_INCLUDE_DIRS}
)
# 设置要链接的OpenCV库
target_link_libraries(my_node
${OpenCV_LIBS} # 链接 OpenCV 库
opencv_core opencv_imgcodecs opencv_highgui
)
# 设置要链接的OpenCV库
ament_target_dependencies(my_node rclcpp cv_bridge)
# 安装节点
install(TARGETS
my_node
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/opencv-4.10.0/lib/cmake/opencv4" ${CMAKE_PREFIX_PATH})
CMAKE_PREFIX_PATH
是 CMake 用来查找包和库的路径的一个变量,CMake 中调用 find_package()
查找库时,CMake 会在 CMAKE_PREFIX_PATH 中指定的路径下搜索库。
find_package(OpenCV 4.10.0 REQUIRED COMPONENTS)
确保 OpenCV 4.10.0 库被找到,并且能够被正确配置。
REQUIRED
:如果找不到指定版本的 OpenCV,或者 OpenCV 配置有问题,CMake 会报错并停止执行。
COMPONENTS
:如果需要使用 OpenCV 的特定模块,可以在 COMPONENTS 后面列出它们的名字,如:find_package(OpenCV 4.10.0 REQUIRED COMPONENTS core imgproc)
,CMake 会查找 OpenCV 4.10.0 版本,并确保找到 core 和 imgproc 这两个模块。
运行上面的CMakeList.txt输出如下:
opencv path: /home/boss_dog/000_dev/tag_test/src/my_package/lib/opencv-4.10.0/lib/cmake/opencv4
opencv version: 4.10.0
opencv include dir: /home/boss_dog/000_dev/tag_test/src/my_package/lib/opencv-4.10.0/include/opencv4
opencv libraries: opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_alphamat;opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_ccalib;opencv_datasets;opencv_dnn_objdetect;opencv_dnn_superres;opencv_dpm;opencv_face;opencv_freetype;opencv_fuzzy;opencv_hdf;opencv_hfs;opencv_img_hash;opencv_intensity_transform;opencv_line_descriptor;opencv_mcc;opencv_optflow;opencv_phase_unwrapping;opencv_plot;opencv_quality;opencv_rapid;opencv_reg;opencv_rgbd;opencv_saliency;opencv_sfm;opencv_shape;opencv_signal;opencv_stereo;opencv_structured_light;opencv_superres;opencv_surface_matching;opencv_text;opencv_tracking;opencv_videostab;opencv_wechat_qrcode;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto;opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_alphamat;opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_ccalib;opencv_datasets;opencv_dnn_objdetect;opencv_dnn_superres;opencv_dpm;opencv_face;opencv_freetype;opencv_fuzzy;opencv_hdf;opencv_hfs;opencv_img_hash;opencv_intensity_transform;opencv_line_descriptor;opencv_mcc;opencv_optflow;opencv_phase_unwrapping;opencv_plot;opencv_quality;opencv_rapid;opencv_reg;opencv_rgbd;opencv_saliency;opencv_sfm;opencv_shape;opencv_signal;opencv_stereo;opencv_structured_light;opencv_superres;opencv_surface_matching;opencv_text;opencv_tracking;opencv_videostab;opencv_wechat_qrcode;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto
- my_node.cpp
#include <rclcpp/rclcpp.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/aruco/charuco.hpp>
class MyNode : public rclcpp::Node
{
public:
MyNode() : Node("opencv_example_node")
{
// // 创建一个简单的OpenCV图像
// Mat image = Mat::zeros(200, 200, CV_8UC3);
// rectangle(image, Point(50, 50), Point(150, 150), Scalar(0, 0, 255), 2);
// // 保存图像
// imwrite("/tmp/test_image.jpg", image);
// RCLCPP_INFO(this->get_logger(), "Image saved at /tmp/test_image.jpg");
}
};
int main(int argc, char **argv)
{
std::cout << "OpenCV version: " << CV_VERSION << std::endl;
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MyNode>());
rclcpp::shutdown();
return 0;
}
编写代码中,引入opencv相关头文件后,可以跳转到源文件看下是否依赖的是指定的opencv版本还是系统自带的opencv。
3.解决节点运行找不到OpenCV相关库的问题
通过 ros2 run my_test my_node 启动节点时,会报错找不到相关的OpenCV库,需要提前将引用到的OpenCV模块的动态库拷贝到 install/节点名/lib
目录下: