如何把yolov5的C++代码改成ROS的功能包

目录

一、添加ROS工作空间,把源码放到catkin_ws/src目录下

目录结构与一般的ROS工作空间类似,把yolov5的包放在catkin_ws/src下,作为一个ROS的功能包。

二、改CMakeLists.txt和添加package.xml

2.1 修改CMakeLists.txt

一般而言,C++版本的yolov5都有CMakeLists.txt,因此需要在其中添加ROS的环境,生成ROS的可执行文件。

2.1.1 添加ROS的catkin包

find_package(catkin REQUIRED
        COMPONENTS
            roscpp
            nav_msgs
            sensor_msgs
            std_msgs
            image_transport
            message_generation
            cv_bridge
            tf2
        )

2.1.2 添加自定义msg消息类型

add_message_files(
    FILES 
    single_res.msg 
    multi_res.msg 
    yolo_detection.msg

)

generate_messages(
    DEPENDENCIES
    std_msgs
    sensor_msgs
)

2.1.3 添加当前包所依赖的其他 Catkin 包

catkin_package(
    CATKIN_DEPENDS
        roscpp
        nav_msgs
        image_transport
        std_msgs
        cv_bridge
        sensor_msgs
    message_runtime
        tf2
)

CATKIN_DEPENDS:列出当前包所依赖的其他 Catkin 包。这些依赖将自动添加到其他包需要链接和包含当前包时所需的依赖中。

2.1.4 添加依赖库

target_link_libraries(yolov5s ${catkin_LIBRARIES})

至此,CMakeLists.txt文件修改完成!

注意CMakeLists.txt文件中已经有了生成yolov5的可执行文件的命令,不需要额外再生成!

add_executable(yolov5s ${PROJECT_SOURCE_DIR}/yolov5s.cpp ${PROJECT_SOURCE_DIR}/videoCapture.cpp)

2.1.5 完整CMakeLists.txt文件

cmake_minimum_required(VERSION 2.6)
project(yolov5)
add_definitions(-std=c++11)

option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)

#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
find_package(CUDA REQUIRED)
find_package(catkin REQUIRED
        COMPONENTS
            roscpp
            nav_msgs
            sensor_msgs
            std_msgs
            image_transport
        message_generation
        cv_bridge
            tf2
)

#find_package(cv_bridge)
#include_directories(${cv_bridge_INCLUDE_DIRS})

find_package(OpenCV 4)
include_directories(${OpenCV_INCLUDE_DIRS})

set(CUDA_NVCC_PLAGS ${CUDA_NVCC_PLAGS};-std=c++11;-g;-G;-gencode;arch=compute_30;code=sm_30)

include_directories(${PROJECT_SOURCE_DIR}/include ${catkin_INCLUDE_DIRS})
if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
    message("embed_platform on")
    include_directories(/usr/local/cuda/targets/aarch64-linux/include)
    link_directories(/usr/local/cuda/targets/aarch64-linux/lib)
else()
    message("embed_platform off")
    include_directories(/usr/local/cuda/include)
    link_directories(/usr/local/cuda/lib64)
endif()

add_message_files(
    FILES 
    single_res.msg 
    multi_res.msg 
    yolo_detection.msg
)

generate_messages(
    DEPENDENCIES
    std_msgs
    sensor_msgs
)

catkin_package(
    CATKIN_DEPENDS
        roscpp
        nav_msgs
        image_transport
        std_msgs
        cv_bridge
        sensor_msgs
    message_runtime
        tf2
)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED")

cuda_add_library(yololayer SHARED ${PROJECT_SOURCE_DIR}/yololayer.cu)

message("${OpenCV_INCLUDE_DIRS}")

add_executable(yolov5s ${PROJECT_SOURCE_DIR}/yolov5s.cpp ${PROJECT_SOURCE_DIR}/videoCapture.cpp)
target_link_libraries(yolov5s nvinfer)
target_link_libraries(yolov5s cudart)
target_link_libraries(yolov5s yololayer)
target_link_libraries(yolov5s ${OpenCV_LIBRARIES})
target_link_libraries(yolov5s ${catkin_LIBRARIES})
#target_link_libraries(yolov5s ${cv_bridge_LIBRARIES})

add_definitions(-O2 -pthread)

2.2 添加package.xml文件

<?xml version="1.0"?>
<package format="2">
    <name>yolov5</name>
    <version>1.17.1</version>
    <description>
        yolo v5.
    </description>
    <author>Brian Gerkey, Tony Pratkanis</author>
    <author>contradict@gmail.com</author>
    <maintainer email="davidvlu@gmail.com">David V. Lu!!</maintainer>
    <maintainer email="mfergs7@gmail.com">Michael Ferguson</maintainer>
    <maintainer email="ahoy@fetchrobotics.com">Aaron Hoy</maintainer>
    <url>http://wiki.ros.org/map_server</url>
    <license>BSD</license>

    <buildtool_depend>catkin</buildtool_depend>

    <depend>nav_msgs</depend>
    <depend>message_generation</depend>
    <depend>message_runtime</depend>
    <depend>roscpp</depend>
    <depend>sensor_msgs</depend>  
    <depend>std_msgs</depend>
    <depend>image_transport</depend>
    <depend>cv_bridge</depend>  
    <depend>tf2</depend>

</package>

该文件中主要在<depend>标签中添加所依赖的ROS包即可!

三、源码添加ROS头文件和创建ROS节点

3.1 添加ROS头文件

#include <ros/ros.h>
#include "nav_msgs/MapMetaData.h" 
#include <sensor_msgs/CameraInfo.h>
#include <image_transport/image_transport.h> //  ROS的图像发布器
#include <cv_bridge/cv_bridge.h>

#include "yolov5/yolo_detection.h" // 自定义消息文件
#include "yolov5/single_res.h" // 自定义消息文件

将ROS的头文件包含在yolov5.cpp具体实现文件中。

3.2 创建并运行ROS节点

在主函数中添加下面代码,创建ROS节点。

int main(int argc, char** argv) {
    ros::init(argc, argv, "yolov5");
    xxx

回到工作空间目录下
cd ~/catkin_yolov5/src

重新编译
catkin_make

添加工作空间环境
source devel/setup.bash

用ROS命令启动程序
roscore
rosrun yolov5 yolov5s

至此,已经将一个普通的C++程序改造为一个ROS程序,并且可以以ROS命令启动该程序!

四、源码添加ROS话题发布数据

将普通C++程序改为ROS程序的主要目的是将其纳入ROS通信体系,这样其计算结果以ROS的topic形式发送出来,也可接收其它ROS节点的数据。

4.1 创建发布对象

    ros::NodeHandle nh; // 节点句柄
    ros::Publisher yolo_res_pub = nh.advertise<yolov5::yolo_detection>("yolo_res",1); //自定义消息话题
    image_transport::ImageTransport it(nh); // ROS的图像发布器的handle
    image_transport::Publisher pub = it.advertise("image_yolo", 1); // ROS的图像发布器

4.2 发布ROS消息

    yolov5::yolo_detection detect_res; // 自定义消息类型的数据
    yolov5::single_res s_res;
    yolov5::multi_res m_res;
        for (int b = 0; b < fcount; b++) { // batch_res为当前帧所检测的所有类,二维vector
            auto& res = batch_res[b]; // res为当前帧所检测的某一类的所有框,一维vector
            for (size_t j = 0; j < res.size(); j++) { // 提取boundingbox
                s_res.conf = res[j].conf;
                s_res.class_id = res[j].class_id;
                s_res.bbox[0] = res[j].bbox[0];
                s_res.bbox[1] = res[j].bbox[1];
                s_res.bbox[2] = res[j].bbox[2];
                s_res.bbox[3] = res[j].bbox[3];
                m_res.single_res_arrary.push_back(s_res);
            }
            detect_res.yolo_res.push_back(m_res);
            m_res.single_res_arrary.clear();
            // 将cv::mat数据类型转换为ROS的图像类型,这里用指针,速度更快!
            sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", pr_img).toImageMsg(); 
            pub.publish(msg);
        }

        yolo_res_pub.publish(detect_res); // 发布所有类别的框的消息
        detect_res.yolo_res.clear(); // 清空

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,002评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,777评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,341评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,085评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,110评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,868评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,528评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,422评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,938评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,067评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,199评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,877评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,540评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,079评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,192评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,514评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,190评论 2 357

推荐阅读更多精彩内容