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

How to save sensor_msgs/image as .jpeg or .bmp files. Is OpenCV indispensable?

asked 2011-07-15 09:44:01 -0600

Sergio MP gravatar image

Hello to all,

I'm working with the Point Cloud Library and the Kinect openni_kinect node and I want to save the sensor_msgs/Image published to the "/camera/rgb/image_color" topic of the openni_node as .jpeg or .bmp files. It seems like I need to use CvBridge to transform the ros msg to the OpenCV format and save it from there.

I'm not using OpenCV for anything else (for now at least) and that's why I ask: Is this the way I should do it?

Thank you for reading! Cheers,

Sergio MP

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
4

answered 2011-07-17 23:42:03 -0600

abroun gravatar image

The advantage of using OpenCV is that you'll be able save you image in a variety of formats using just one or two lines.

If you want to avoid using OpenCV then you either have to roll your own code for saving an image in your chosen format, or use one of the standard libraries such as libJPEG. The choice you make depends upon the amount of time you have to write, test and debug your own code versus any aversion you may have to linking in another library.

A quick and dirty solution that I sometimes use when I just want to dump an image out is to use one of the Netpbm ASCII formats. This will result in huge files, but it's not meant to be an elegant solution. ;)

Something like this should work for you. Use a filename with a .ppm extension and Ubuntu or the GIMP will be able to open it.

void SaveImageAsPPM( const sensor_msgs::ImageConstPtr& msg, const char* filename )
{
  if ( msg->encoding != "rgb8" )
  {
    return;  // Can only handle the rgb8 encoding
  }

  FILE* file = fopen( filename, "w" );

  fprintf( file, "P3\n" );
  fprintf( file, "%i %i\n", msg->width, msg->height );
  fprintf( file, "255\n" );

  for ( uint32_t y = 0; y < msg->height; y++ )
  {
    for ( uint32_t x = 0; x < msg->width; x++ )
    {
      // Get indices for the pixel components
      uint32_t redByteIdx = y*msg->step + 3*x;
      uint32_t greenByteIdx = redByteIdx + 1;
      uint32_t blueByteIdx = redByteIdx + 2;

      fprintf( file, "%i %i %i ", 
        msg->data[ redByteIdx ], 
        msg->data[ greenByteIdx ], 
        msg->data[ blueByteIdx ] );
    }
    fprintf( file, "\n" );
  }

  fclose( file );
}
edit flag offensive delete link more
0

answered 2011-07-21 03:06:31 -0600

Sergio MP gravatar image

Thank you very much! I' ll just try this quick solution for it's not an essential part of my project. If my tutor doesn't like I'll just have to use OpenCV =P.

Thank you!

Cheers,

Sergio Martini Popoli

edit flag offensive delete link more

Question Tools

Stats

Asked: 2011-07-15 09:44:01 -0600

Seen: 2,928 times

Last updated: Jul 21 '11