ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ROS常用消息之Image

ROS常用消息之Image sensor_msgs/Image —— 图像消息官方文档sensor_msgs/Image Message源码位置File: sensor_msgs/Image.msg1. 概述sensor_msgs/Image用于承载一帧未压缩的图像以**行优先row-major**的方式存储像素数据是 ROS 视觉应用中相机驱动、图像处理、视觉 SLAM 等最基础的消息。典型使用场景相机驱动USB / 单目 / 双目对外发布图像图像处理节点灰度化、边缘检测、目标检测的输入与输出视觉 SLAMORB-SLAM、VINS的图像输入何时使用当需要传输未压缩图像时使用本消息。注意需要降低带宽时可用sensor_msgs/CompressedImage需要深度数据时可用sensor_msgs/Imageencoding为16UC1或直接使用点云。2. 消息定义Raw Message Definition#This message contains an uncompressed image#(0,0)is at top-left corner of image#Header header # Header timestamp should be acquisition time of image#Header frame_id should be optical frame of camera#originof frame should be optical center of camera#x should point to the right in the image #y should point down in the image #z should point into to plane of the image#If the frame_id hereandthe frame_id of the CameraInfo#messageassociated with the image conflict#thebehavior is undefineduint32 height # image height,that is,number of rows uint32 width # image width,that is,number of columns#The legal valuesforencoding are in file src/image_encodings.cpp#If you want to standardize anewstring format,join#ros-userslists.sourceforge.netandsend an email proposing anewencoding.string encoding # Encoding of pixels--channel meaning,ordering,size#takenfrom the list of strings in include/sensor_msgs/image_encodings.huint8 is_bigendian # isthisdata bigendian?uint32 step # Full row length in bytes uint8[]data # actual matrix data,sizeis(step*rows)Compact Message Definitionstd_msgs/Header header uint32 height uint32 width string encoding uint8 is_bigendian uint32 step uint8[]data3. 字段速查表字段类型说明headerstd_msgs/Header时间戳为图像采集时刻frame_id为相机光心坐标系optical frameheightuint32图像高度即行数像素widthuint32图像宽度即列数像素encodingstring像素编码格式通道含义、顺序、位深is_bigendianuint8数据是否按大端存储0 小端1 大端stepuint32一行数据的字节数含行填充不一定等于width × 每像素字节数datauint8[]像素数据本体长度为step × height字节内存布局data总大小 step × height像素(row, col)的字节偏移 row × step col × 每像素字节数。4. 核心概念坐标约定图像左上角为(0, 0)x 向右y 向下区别于常见数学坐标。相机光轴指向相机前方ZX指向图像右侧、Y指向图像下方。header.frame_id应为相机光心坐标系如camera_link下的camera_optical_frame。常用编码格式encoding编码含义每像素字节数mono88 位灰度图1mono1616 位灰度图2rgb88 位 RGB 彩色图3bgr88 位 BGR 彩色图OpenCV 默认3rgba8/bgra88 位 RGBA / BGRA416UC116 位单通道无符号深度图常用232FC132 位单通道浮点4避坑提醒OpenCV 默认使用BGR顺序ROS 图像通常是RGB。若用cv_bridge转换时选错编码会出现红蓝通道互换。与 OpenCV 的互转cv_bridge#includecv_bridge/cv_bridge.h#includesensor_msgs/image_encodings.h#includeopencv2/opencv.hpp// ROS Image - cv::Matcv_bridge::CvImagePtr cv_ptrcv_bridge::toCvCopy(img_msg,sensor_msgs::image_encodings::BGR8);// cv::Mat - ROS Imagesensor_msgs::ImagePtr img_msgcv_bridge::CvImage(std_msgs::Header(),bgr8,cv_mat).toImageMsg();5. 实践案例案例一订阅图像转换为 OpenCV 灰度图C#includeros/ros.h#includesensor_msgs/Image.h#includecv_bridge/cv_bridge.h#includesensor_msgs/image_encodings.h#includeopencv2/imgproc/imgproc.hppvoidimageCallback(constsensor_msgs::Image::ConstPtrmsg){try{// 1. ROS 图像 - cv::MatBGR8cv_bridge::CvImagePtr cv_ptrcv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::BGR8);// 2. 转为灰度图cv::Mat gray;cv::cvtColor(cv_ptr-image,gray,cv::COLOR_BGR2GRAY);// 3. 在此处处理 gray ...ROS_INFO(received %dx%d image, gray size %dx%d,msg-width,msg-height,gray.cols,gray.rows);}catch(cv_bridge::Exceptione){ROS_ERROR(cv_bridge exception: %s,e.what());}}intmain(intargc,char**argv){ros::init(argc,argv,image_processor);ros::NodeHandle nh;ros::Subscriber subnh.subscribe(/camera/image_raw,1,imageCallback);ros::spin();return0;}案例二手动访问像素值不依赖 cv_bridge#includeros/ros.h#includesensor_msgs/Image.h#includesensor_msgs/image_encodings.h// 直接通过 step 与 encoding 定位像素以 mono8 为例voidaccessPixelManually(constsensor_msgs::Image::ConstPtrmsg,size_t row,size_t col,uint8_tvalue){if(msg-encoding!sensor_msgs::image_encodings::MONO8){ROS_ERROR(This example only supports mono8, got %s,msg-encoding.c_str());return;}// 每像素 1 字节偏移 row * step colsize_t offsetrow*msg-stepcol;if(offsetmsg-data.size())return;valuemsg-data[offset];}案例三发布图像消息C从 cv::Mat 发布#includeros/ros.h#includesensor_msgs/Image.h#includecv_bridge/cv_bridge.h#includeopencv2/core/core.hpp#includeopencv2/imgproc/imgproc.hppintmain(intargc,char**argv){ros::init(argc,argv,image_publisher);ros::NodeHandle nh;ros::Publisher img_pubnh.advertisesensor_msgs::Image(/image,1);ros::Rateloop_rate(30);// 30 Hz// 生成一张纯色测试图640x480三通道 BGRcv::Matframe(480,640,CV_8UC3,cv::Scalar(0,0,255));while(ros::ok()){sensor_msgs::ImagePtr msgcv_bridge::CvImage(std_msgs::Header(),bgr8,frame).toImageMsg();msg-header.stampros::Time::now();msg-header.frame_idcamera_optical_frame;img_pub.publish(msg);loop_rate.sleep();}return0;}6. 常见问题与避坑问题说明 / 正确做法红蓝通道互换OpenCV 是BGRROS 常用RGB用cv_bridge时注意encoding直接按width × height索引data应使用row * step col因为step可能大于width × 每像素字节数含行对齐填充图像不连续isContinuous()为 falsestep与理论值不同处理像素时务必用step而非硬编码忽略header.stamp视觉 SLAM 等强依赖时间戳驱动应填采集时刻encoding与数据不符读取前先检查msg-encoding不同位深 / 通道数的索引方式不同高频大图卡顿未压缩图像占用带宽大可改用CompressedImage或降低分辨率frame_id与 CameraInfo 冲突图像消息与关联的sensor_msgs/CameraInfo的frame_id必须一致否则行为未定义
返回列表