ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Creating sensor_msgs::image from scratch

asked 2014-10-26 15:45:37 -0600

Ruud gravatar image

Hi all,

Since OpenCV is not compiling right on my machine, I want to create and fill a sensor_msgs::Image ( http://docs.ros.org/api/sensor_msgs/h... ) 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

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
3

answered 2014-10-27 14:41:12 -0600

Ruud gravatar image

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);
edit flag offensive delete link more

Comments

Hi,

I think there is a mistake in your code.
I think that: ... output_image.step = 3 * height; ... is wrong:
I think it should be : output_image.step = 3 * width;
Some explainations here (in the 1st response): img-step

runfaster gravatar image runfaster  ( 2017-12-10 18:06:29 -0600 )edit
0

answered 2015-10-08 05:31:19 -0600

John Waffle gravatar image

You could have used the fillImage method: http://docs.ros.org/diamondback/api/s...

Related question: http://answers.ros.org/question/19616...

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2014-10-26 15:45:37 -0600

Seen: 5,429 times

Last updated: Oct 08 '15