美文网首页
自定义 RGBD_Image.msg 并制作 RGBD 发布器/

自定义 RGBD_Image.msg 并制作 RGBD 发布器/

作者: 谢小帅 | 来源:发表于2019-05-10 21:57 被阅读0次

    RGBD_Image.msg

    • 包含2个 sensor_msgs/Image,分别存储 rgb,depth
    • 添加1个 std_msgs/Header,存储图像时间戳,seq;sensor Image 自带的 header 就不用赋值了。
    # use this header as both RGB & Depth header
    std_msgs/Header header
    
    # not use rgb/depth own header(in code)
    sensor_msgs/Image rgb
    sensor_msgs/Image depth
    

    stereo_rgbd_puber.cpp

    1. opencv 读入 cv::Mat rgb,depth
    2. cv_bridge 将 cv::Mat 转化为 sensor_msgs::Image
    3. 发布

    注意:

    • n.advertise<stereo::RGBD_Image> 指定为自定义的 msg
    • cv_bridge 图像转化编码:
      RGB 编码 bgr8,depth_8 编码 mono8,depth_16 编码 mono16
    #include <ros/ros.h>
    #include <std_msgs/Header.h>
    #include <sensor_msgs/Image.h>
    
    #include <stereo/RGBD_Image.h>
    #include <cv_bridge/cv_bridge.h>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    
    
    int main(int argc, char **argv) {
        ros::init(argc, argv, "stereo_rgbd_puber");
        ros::NodeHandle n;
        ros::Publisher chatter_pub = n.advertise<stereo::RGBD_Image>("/stereo/rgbd/image", 1000); // Note: change msg type!
        ros::Rate loop_rate(10); // 10fps
    
        stereo::RGBD_Image rgbd_msg;
    
        // msg source
        cv::Mat rgb = cv::imread("/home/nvidia/wali_ws/src/stereo/img/rgb.jpg", cv::IMREAD_COLOR);
        cv::Mat depth = cv::imread("/home/nvidia/wali_ws/src/stereo/img/depth.png", cv::IMREAD_ANYDEPTH);
    
        // header
        std_msgs::Header header; // not necessary
        header.frame_id = "/stereo/rgbd/image"; // detailed header info
        header.stamp = ros::Time::now(); // time stamp
    
        unsigned int count = 0;
        while (ros::ok()) {
            header.seq = count;
            rgbd_msg.header = header;
            cv_bridge::CvImage(std_msgs::Header(), "bgr8", rgb).toImageMsg(rgbd_msg.rgb);
            cv_bridge::CvImage(std_msgs::Header(), "mono16", depth).toImageMsg(rgbd_msg.depth);
            // though default sensor_msgs/Image use uint8[] data, we use "mono16" can get 16bit data
            ROS_INFO("send RGBD %d", count);
    
            chatter_pub.publish(rgbd_msg);
    
            ros::spinOnce();
            loop_rate.sleep();
            ++count;
        }
    
        return 0;
    }
    

    stereo_rgbd_suber.cpp 订阅 RGBD_Image 并显示

    • cv::imshow() 显示 depth_16 要先转化为 depth_8UC3
    #include <ros/ros.h>
    #include <std_msgs/Header.h>
    #include <sensor_msgs/Image.h>
    
    #include <stereo/RGBD_Image.h>
    #include <cv_bridge/cv_bridge.h>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    
    cv_bridge::CvImagePtr cv_ptr_rgb, cv_ptr_depth;
    cv::Mat rgb, depth;
    
    void chatterCallback(const stereo::RGBD_Image::ConstPtr &msg) {
        ROS_INFO("get RGBD %d", msg->header.seq);
        cv_ptr_rgb = cv_bridge::toCvCopy(msg->rgb, "bgr8");
        cv_ptr_depth = cv_bridge::toCvCopy(msg->depth, "mono16"); // 16bits depth
        rgb = cv_ptr_rgb->image;
        depth = cv_ptr_depth->image;
        cv::imshow("rgb", rgb);
    
        // cvt 1C depth to 3C for imshow
        cv::Mat depth_show(depth.rows, depth.cols, CV_8UC3);
        for (int h = 0; h < depth.rows; ++h) {
            for (int w = 0; w < depth.cols; ++w) { // ushort for 16 bit
                uchar val = (uchar) (depth.at<ushort>(h, w) / 256); // 16->8
                depth_show.at<cv::Vec3b>(h, w) = {val, val, val};
            }
        }
        cv::imshow("depth", depth_show); // default 3 channels
        cv::waitKey(30);
    }
    
    
    int main(int argc, char **argv) {
        ros::init(argc, argv, "stereo_rgbd_suber");
        ros::NodeHandle n;
        ros::Subscriber sub = n.subscribe("/stereo/rgbd/image", 1000, chatterCallback);
        ros::spin();
        return 0;
    }
    
    send, get, and show

    CMakeLists.txt

    • 添加 msg 生成
    • 添加 opencv 库
    cmake_minimum_required(VERSION 2.8.3)
    project(stereo)
    
    ## Compile as C++11, supported in ROS Kinetic and newer
    add_compile_options(-std=c++11)
    
    find_package(catkin REQUIRED COMPONENTS
            roscpp
            rospy
            std_msgs
            sensor_msgs
            message_generation
            cv_bridge
            )
    
    find_package(OpenCV REQUIRED)
    
    
    add_message_files(
            FILES
            RGBD_Image.msg
    )
    
    ## Generate added messages and services with any dependencies listed here
    generate_messages(
            DEPENDENCIES
            std_msgs
            sensor_msgs # use Image
    )
    
    catkin_package(
            #  INCLUDE_DIRS include
            #  LIBRARIES stereo
            CATKIN_DEPENDS roscpp rospy std_msgs sensor_msgs message_runtime
            #  DEPENDS system_lib
    )
    
    ###########
    ## Build ##
    ###########
    
    ## Specify additional locations of header files
    ## Your package locations should be listed before other locations
    include_directories(
            ${catkin_INCLUDE_DIRS}
            ${OpenCV_INCLUDE_DIRS}
    )
    
    ## Declare a C++ executable
    ## With catkin_make all packages are built within a single CMake context
    ## The recommended prefix ensures that target names across packages don't collide
    add_executable(stereo_rgbd_puber src/stereo_rgbd_puber.cpp)
    add_executable(stereo_rgbd_suber src/stereo_rgbd_suber.cpp)
    
    ## Add cmake target dependencies of the executable
    ## same as for the library above
    
    # rgbd_puber
    add_dependencies(stereo_rgbd_puber
            ${${PROJECT_NAME}_EXPORTED_TARGETS}
            ${catkin_EXPORTED_TARGETS}
            )
    target_link_libraries(stereo_rgbd_puber
            ${catkin_LIBRARIES}
            ${OpenCV_LIBRARIES}
            )
    
    # rgbd_suber
    add_dependencies(stereo_rgbd_suber
            ${${PROJECT_NAME}_EXPORTED_TARGETS}
            ${catkin_EXPORTED_TARGETS}
            )
    target_link_libraries(stereo_rgbd_suber
            ${catkin_LIBRARIES}
            ${OpenCV_LIBRARIES}
            )
    

    package.xml

    <?xml version="1.0"?>
    <package format="2">
        <name>stereo</name>
        <version>0.0.0</version>
        <description>The stereo package</description>
        <maintainer email="nvidia@todo.todo">nvidia</maintainer>
        <license>TODO</license>
    
        <buildtool_depend>catkin</buildtool_depend>
        <build_depend>roscpp</build_depend>
        <build_depend>rospy</build_depend>
        <build_depend>std_msgs</build_depend>
        <build_depend>sensor_msgs</build_depend>
        <build_depend>message_generation</build_depend>
    
        <build_export_depend>roscpp</build_export_depend>
        <build_export_depend>rospy</build_export_depend>
        <build_export_depend>std_msgs</build_export_depend>
        <build_export_depend>sensor_msgs</build_export_depend>
        <build_export_depend>message_generation</build_export_depend>
    
        <exec_depend>roscpp</exec_depend>
        <exec_depend>rospy</exec_depend>
        <exec_depend>std_msgs</exec_depend>
        <exec_depend>sensor_msgs</exec_depend>
        <exec_depend>message_runtime</exec_depend>
    
        <!-- The export tag contains other, unspecified, tags -->
        <export>
            <!-- Other tools can request additional information be placed here -->
    
        </export>
    </package>
    

    相关文章

      网友评论

          本文标题:自定义 RGBD_Image.msg 并制作 RGBD 发布器/

          本文链接:https://www.haomeiwen.com/subject/rywzoqtx.html