Unity转ROS2:C#中字节数组转sensor_msgs.msg.CompressedImage方法
Unity相机图像转ROS2 sensor_msgs.CompressedImage 实现方案
问题描述
我需要从Unity获取相机图像,并将其以sensor_msgs.msg.CompressedImage类型的消息发送至ROS2。现有代码中已完成图像字节数组的生成,需要实现ByteArrayToImage函数将字节数组转换为对应的消息类型,请问该函数应如何编写?
现有代码片段:
Texture2D snapshot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false); snapCam.Render(); RenderTexture.active = snapCam.targetTexture; snapshot.ReadPixels(new Rect(0,0,resWidth, resHeight), 0, 0); byte[] bytes = snapshot.EncodeToPNG(); sensor_msgs.msg.CompressedImage ImageMsg = new sensor_msgs.msg.CompressedImage(); // TO DO : ImageMsg.Data = ByteArrayToImage(bytes); image_pub.Publish(ImageMsg);
解决方案
其实你不需要单独写ByteArrayToImage函数——因为sensor_msgs.msg.CompressedImage的Data字段本身就是字节数组类型,直接赋值即可。不过需要补充消息的其他必要字段,才能让ROS2正确识别这个压缩图像。
完整处理代码
Texture2D snapshot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false); snapCam.Render(); RenderTexture.active = snapCam.targetTexture; snapshot.ReadPixels(new Rect(0,0,resWidth, resHeight), 0, 0); byte[] bytes = snapshot.EncodeToPNG(); sensor_msgs.msg.CompressedImage ImageMsg = new sensor_msgs.msg.CompressedImage(); // 填充压缩图像消息的必要字段 ImageMsg.Header.Stamp = new builtin_interfaces.msg.Time { Sec = (int)Time.time, Nanosec = (int)((Time.time - (int)Time.time) * 1e9) }; ImageMsg.Header.FrameId = "camera_frame"; // 替换为你的相机坐标系ID ImageMsg.Format = "png"; // 与EncodeToPNG对应,格式填png ImageMsg.Data = bytes; // 直接将PNG字节数组赋值给Data字段 image_pub.Publish(ImageMsg);
关键点说明
CompressedImage的Data字段类型就是byte[],所以不需要额外转换,直接把EncodeToPNG得到的字节数组赋值即可。- 必须填充
Header的时间戳和坐标系ID,否则ROS2节点无法正确解析图像的时序和空间信息。 Format字段要和编码格式匹配:用PNG就填"png",用JPEG就填"jpeg"。
封装成ByteArrayToImage函数的实现
如果一定要封装成函数,可参考以下代码:
private sensor_msgs.msg.CompressedImage ByteArrayToImage(byte[] imageBytes, string frameId) { var compressedImage = new sensor_msgs.msg.CompressedImage(); // 设置头部信息 compressedImage.Header.Stamp = new builtin_interfaces.msg.Time { Sec = (int)Time.time, Nanosec = (int)((Time.time - (int)Time.time) * 1e9) }; compressedImage.Header.FrameId = frameId; // 设置图像格式和数据 compressedImage.Format = "png"; compressedImage.Data = imageBytes; return compressedImage; }
调用方式:
sensor_msgs.msg.CompressedImage ImageMsg = ByteArrayToImage(bytes, "camera_frame"); image_pub.Publish(ImageMsg);
内容的提问来源于stack exchange,提问作者tgr
相关产品推荐
相关产品推荐

