问题描述
我目前正在尝试编写ROS发布者/订阅者设置,该设置可传递由PIL打开的图像二进制文件。由于操作限制,我不想使用OpenCV,我想知道是否可以使用OpenCV。这是我当前的代码:
#!/usr/bin/env python
import rospy
from PIL import Image
from sensor_msgs.msg import Image as sensorImage
from rospy.numpy_msg import numpy_msg
import numpy
def talker():
pub = rospy.Publisher('image_stream',numpy_msg(sensorImage),queue_size=10)
rospy.init_node('image_publisher',anonymous=False)
rate = rospy.Rate(0.5)
while not rospy.is_shutdown():
im = numpy.array(Image.open('test.jpg'))
pub.publish(im)
rate.sleep()
if __name__ == '__main__'
try:
talker()
except ROSInterruptException:
pass
在pub.publish(im)上尝试抛出的错误:
TypeError: Invalid number of arguments,args should be ['header','height','width','encoding','is_bigendian','step','data'] args are (array([[[***array data here***]]],dtype=uint8),)
我如何将图像转换为正确的格式,或者是否存在仅支持通过ROS连接发送原始二进制文件的转换方法/不同的消息类型?
谢谢
解决方法
我对ROS一无所知,但我经常使用 PIL ,因此,如果其他人知道更好,请ping通我,然后我将删除此“最佳猜测” em>答案。
因此,似乎您需要从PIL Image
制作类似this的东西。所以你需要:
- “标题”,
- “身高”,
- “宽度”,
- “编码”,
- 'is_bigendian',
- “步骤”,
- “数据”
因此,假设您这样做:
im = Image.open('test.jpg')
您应该可以使用:
- 您需要解决的问题 来自
-
PIL Image
来自 -
PIL Image
- 可能
const std::string RGB8 = "rgb8"
- 可能无关紧要,因为数据是8位的
- 可能
im.width * 3
,因为它是每个像素RGB 3个字节 -
np.array(im).tobytes()
im.height
的im.width
的在任何人将这个答案记下来之前,没有人说答案必须是完整的-他们可以是“很有帮助” !
请注意,如果您输入的图像是PNG格式,则应检查im.mode
,如果它是"P"
(即调色板模式),则立即运行:
im = im.convert('RGB')
确保它是3通道RGB。
请注意,如果输入图像为PNG格式并包含Alpha通道,则应将encoding
更改为"rgba8"
并设置step = im.width * 4
。
实际上Mark Setchell's answer可以完美运行(在此示例中忽略了alpha通道):
#!/usr/bin/env python
import rospy
import urllib2 # for downloading an example image
from PIL import Image
from sensor_msgs.msg import Image as SensorImage
import numpy as np
if __name__ == '__main__':
pub = rospy.Publisher('/image',SensorImage,queue_size=10)
rospy.init_node('image_publisher')
im = Image.open(urllib2.urlopen('https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png'))
im = im.convert('RGB')
msg = SensorImage()
msg.header.stamp = rospy.Time.now()
msg.height = im.height
msg.width = im.width
msg.encoding = "rgb8"
msg.is_bigendian = False
msg.step = 3 * im.width
msg.data = np.array(im).tobytes()
pub.publish(msg)