Creating sensor_msgs::image from scratch
Hi all,
Since OpenCV is not compiling right on my machine, I want to create and fill a sensormsgs::Image (http://docs.ros.org/api/sensormsgs/html/msg/Image.html) from scratch without using the cv_bridge.
I have 3 pointers to a unsigned char array for each channel:
unsigned char* image_pointer_red
unsigned char* image_pointer_green
unsigned char* image_pointer_blue
I have no idea how to fill the fields appropriately in the sensor_msgs::Image message:
string encoding # Encoding of pixels -- channel meaning, ordering, size
# taken from the list of strings in include/sensor_msgs/image_encodings.h
uint8 is_bigendian # is this data bigendian?
uint32 step # Full row length in bytes
uint8[] data # actual matrix data, size is (step * rows)
How should the 'encoding' string be encoded? What is meant by bigendian? What does the full row length in bytes imply? How do I fill the data field appropriately?
I tried searching for examples, there aren't any. They all refer to use the cv_bridge package.
Best, Ruud
Asked by Ruud on 2014-10-26 15:45:37 UTC
Answers
This worked! No cv_bridge required. :)
unsigned char* image_pointer_red;
unsigned char* image_pointer_green;
unsigned char* image_pointer_blue;
uint8_t *uint8_pointer_red = reinterpret_cast<uint8_t*>((unsigned char*)channel_red_pointer[0].L());
uint8_t *uint8_pointer_green = reinterpret_cast<uint8_t*>((unsigned char*)channel_green_pointer[0].L());
uint8_t *uint8_pointer_blue = reinterpret_cast<uint8_t*>((unsigned char*)channel_blue_pointer[0].L());
int height = atoi(height_pointer.ToString().Text());
int width = atoi(width_pointer.ToString().Text());
sensor_msgs::Image output_image;
output_image.header.stamp = ros::Time::now();
output_image.height = height;
output_image.width = width;
output_image.encoding = "rgb8";
output_image.is_bigendian = false;
output_image.step = 3 * height;
for(int i=0; i<(width*height);i++)
{
output_image.data.push_back(uint8_pointer_red[i]);
output_image.data.push_back(uint8_pointer_green[i]);
output_image.data.push_back(uint8_pointer_blue[i]);
}
image_publisher.publish(output_image);
Asked by Ruud on 2014-10-27 14:41:12 UTC
Comments
You could have used the fillImage method: http://docs.ros.org/diamondback/api/sensor_msgs/html/namespacesensor__msgs.html#a0cb3db155a8ed026ad6a11a4753a0385
Related question: http://answers.ros.org/question/196167/filling-sensor_msgsimage-with-uint8_t-buffer-array/
Asked by John Waffle on 2015-10-08 05:31:19 UTC
Comments