Ask Your Question
0

how to save an sensor_msgs/Image to a file?

asked 2011-11-21 16:01:45 -0500

spagi gravatar image

updated 2014-01-28 23:10:49 -0500

ngrennan gravatar image

Hi all. I am trying to pass an image from a Ros node(C++) to a ROSjava node. I managed to make the rosjava node to subscribe to the others topic. The C++ is publishing an image topic and the Rosjava i supposed to write the image in a file.

The problem is that I cannot find an equivalent on Rosjava for the CVBridge that is used in C++ to make the image message a Iplimage file and save it. What I currently do is try to put the message in a byte[] and then read it in a file. But the result is an jpg file 4 times bigger that the one sent and unreadable. Here is the code I use for the C++ node:

int main(int argc, char **argv)

{    
  ros::init(argc, argv, "imagesender");    
  ros::NodeHandle n;    
  ros::Publisher image_pub = n.advertise<sensor_msgs::Image>("image/mysender", 1);

  printf("Loading image...\n");
  IplImage* imgsrc = cvLoadImage( "/home/spagi/ros_workspace/jpgtransfer/src/testimage.jpg" );
  if(!imgsrc){ printf("Could not load image file\n");}
  else{printf("Image Loaded Sucessfully\n");}

  sensor_msgs::ImagePtr imgmsg = sensor_msgs::CvBridge::cvToImgMsg(imgsrc, "bgr8");

  ros::Rate loop_rate(1);
  while (ros::ok())
  {  
    image_pub.publish(imgmsg);  
    ros::spinOnce();
    loop_rate.sleep();
  }    
  return 0;
}

And here the code for the Rosjava node:

 @Override
  public void main(Node node) {

      final FileInputStream fileInputStream=null;

    Preconditions.checkState(this.node == null);
    this.node = node;
    try {
      //final Log log = node.getLog();
      System.out.println("Started main node");
      node.newSubscriber("image/mysender", "sensor_msgs/Image",
          new MessageListener<org.ros.message.sensor_msgs.Image>() {
            @Override
            public void onNewMessage(org.ros.message.sensor_msgs.Image message) {
                System.out.println("Got a new Image message");
                if(x==0){
                    x++;                    
                byte[] byteArray = message.data;
                try {

                //convert array of bytes into file
                FileOutputStream fileOuputStream = 
                          new FileOutputStream("/home/spagi/Desktop/javaccimage.jpg"); 
                fileOuputStream.write(byteArray);
                fileOuputStream.close();            
                System.out.println("Done");                 
                }catch(Exception e){
                    e.printStackTrace();
                }
                }                   
            }

          });
    } catch (Exception e) {
      if (node != null) {
        node.getLog().fatal(e);
      } else {
        e.printStackTrace();
      }
    }
  }

So again my problem is what to do with that message object and how can I make it a file. I dont know if there is an alternative for the publisher on the :

sensor_msgs::CvBridge::cvToImgMsg(imgsrc, "bgr8");
edit retag flag offensive close delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2011-11-21 18:37:51 -0500

Mac gravatar image

The ROS image message isn't a jpeg as a byte array; it's just values as a byte array. There's no compression done automatically (and therefore ROSJava will see just plain data, not compressed data).

Why are you using ROSJava to save the image? If all you want to do is turn Image messages into files, you can do that easily with cv_bridge in python or c++.

This sounds like an XY Problem. What's X?

edit flag offensive delete publish link more

Comments

Basically I need the C++ node to get the image from the kinect and then the rest of my code runs on RosJava because I use the image to query google and do lexical analysis to the results. But I think that I might skip the whole image transfer thing and just store it and ready it a a file in rosjava spagi ( 2011-11-22 13:06:50 -0500 )edit

Touching the filesystem will hurt you. Each element of the Image message data array is one of r, g, or b (as a byte) of the RGB image (assuming it's RGB). Reading that into your Java data structure is just a for loop.

Mac ( 2012-03-26 21:40:20 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

[hide preview]

Stats

Asked: 2011-11-21 16:01:45 -0500

Seen: 1,050 times

Last updated: Nov 21 '11