2017-08-18 219 views
-4

我需要从Android系统的手机,相机得到预览图像数据发布ROS,这里是我的样本代码:ROS-Android中的发布/订阅者时,sensor_msgs.image/compressedImage类型的邮件大小是否会发生变化?

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 
    if(data != null){ 
     Camera.Size size = camera.getParameters().getPreviewSize(); 
     YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null); 

     if(yuvImage != null){ 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
      ChannelBufferOutputStream stream = new ChannelBufferOutputStream(MessageBuffers.dynamicBuffer()); 

      yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 80, baos); 
      yuvImage = null; 

      stream.buffer().writeBytes(baos.toByteArray()); 
      try{ 
       baos.flush(); 
       baos.close(); 
       baos = null; 
      } 
      catch(IOException e){ 
       e.printStackTrace(); 
      } 

      // compressedImage type 
      sensor_msgs.CompressedImage compressedImage = compressedImagePublisher.newMessage(); 
      compressedImage.getHeader().setFrameId("xxx"); // frame id 

      Time curTime = connectedNode.getCurrentTime();  
      compressedImage.getHeader().setStamp(curTime); // time 

      compressedImage.setFormat("jpeg");    // format 
      compressedImage.setData(stream.buffer().copy()); // data 

      stream.buffer().clear(); 
      try { 
       stream.flush(); 
       stream.close(); 
       stream = null; 
      } 
      catch (IOException e) { 
       e.printStackTrace(); 
      } 

      // publish 
      System.out.println("-----Publish: " + compressedImage.getData().array().length + "-----"); 
      compressedImagePublisher.publish(compressedImage); 
      compressedImage = null; 
      System.gc(); 
     } 
     else{ 
      Log.v("Log_Tag", "-----Failed to get yuvImage!-----"); 
     } 
    } 
    else{ 
     Log.v("Log_Tag", "-----Failed to get the preview frame!-----"); 
    } 
} 

而且那么,我已经订阅了主题,只是为了检查消息是否已完全正确发布。就像下面的代码所做的:

@Override 
public void onStart(ConnectedNode node) { 
    this.connectedNode = node; 

    // publisher 
    this.compressedImagePublisher = connectedNode.newPublisher(topic_name, sensor_msgs.CompressedImage._TYPE); 
    // subscriber 
    this.compressedImageSubscriber = connectedNode.newSubscriber(topic_name, sensor_msgs.CompressedImage._TYPE); 
    compressedImageSubscriber.addMessageListener(new MessageListener<CompressedImage>() { 
     @Override 
     public void onNewMessage(final CompressedImage compressedImage) { 
      byte[] receivedImageBytes = compressedImage.getData().array(); 
      if(receivedImageBytes != null && receivedImageBytes.length != 0) { 
       System.out.println("-----Subscribe(+46?): " + receivedImageBytes.length + "-----"); 

       // decode bitmap from byte[] with a strange number of offset and necessary 
       Bitmap bmp = BitmapFactory.decodeByteArray(receivedImageBytes, offset, receivedImageBytes.length - offset); 
       ...  
      } 
     } 
    }); 
} 

我很困惑的数偏移。这意味着图像字节的大小在ROS封装和发布后发生了变化,并且如果我没有设置偏移量,则解码位图将会出错。更奇怪的是,有时偏移量也有变化。

我不知道为什么,我读过有关JPG结构的一些文章,并怀疑它也许头信息的JPG字节的消息。然而,这个问题恰好发生在ros-android场景中。

任何人都有这个好主意?


行!我知道我之前提到的问题和问题很糟糕,这就是为什么它有两个负面因素。对此我感到非常抱歉,我必须通过告诉你们更多的信息来弥补我的错,并且现在让问题更加清楚。

首先,忘记我之前粘贴的所有代码。问题发生在我的ros-android项目中。在这个项目中,我需要将压缩图像类型的传感器消息发送到ros-server,并以发布/订阅的方式获取处理后的图像字节(jpg格式)。在理论上,图像字节大小应该是相同的,而事实上,这已经在我ROS-CROS-C#相同的条件下项目证明。

但是,它们在ros-android中不同,它变得更大!出于这个原因,我不能仅仅从我订阅的图像字节中解码位图,并且必须在图像字节阵列中省略偏移量的异常字节。我不知道为什么会发生在ros-android或ros-java中,这些增加了什么。

我找不到我的代码的原因,这就是为什么我粘贴我的代码详细给你。我真的需要帮助!提前致谢!

Logcat

回答

0

也许我真的需要先检查API之前在这里问的问题。如果我检查了ChannelBuffer在API中的属性,导致属性arrayOffset已经告诉我这个问题的答案,这是一个非常简单的问题!


那么,对于更加谨慎和你们的人的缘故需要澄清我的答案,所以我必须做出详细的解释!

起初,我不得不说,我还是不知道ChannelBuffer类型图像字节数组的数据,这就是如何意味着我仍然不知道为什么会出现很阵列数据之前应该有arrayOffset。为什么我们不能只获取数据?是否真的有一些重要的原因是因为arrayOffset?为了安全起见,还是为了效率?我不知道,我无法从API中找到答案。所以我现在对这个问题真的很厌倦,我厌倦了你们是否对这个问题提出否定的看法,只是放手吧!

徐克回到主题,这个问题可以这样解决:

int offset = compressedImage.getData().arrayOffset(); 
Bitmap bmp = BitmapFactory.decodeByteArray(receivedImageBytes, offset, receivedImageBytes.length - offset); 

OK!我仍然希望有这方面知识的人能告诉我为什么,我会很欣赏这个!如果你们对我这个问题感到厌倦,那就让我们投票结束它吧,我也会很感激!不管怎么说,还是要谢谢你!