ROS中如何订阅和发布图片
How to subscribe and publish images in ROS
我正在尝试订阅“/camera/image_color”主题,该主题是我相机的数据。然后我想在 opencv 中对这些图像做一些巫术,并以特定的频率发布它们。这样我就可以用另一个节点订阅它们。
到目前为止,我已经尝试了以下代码及其许多变体。此时代码什么都不做。没有图像被发布到“/imagetimer”主题。我得到一个输出 "Timing images" 然后没有进一步发生。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import os
import numpy as np
class Nodo(object):
def __init__(self):
# Params
self.image = None
self.br = CvBridge()
# Node cycle rate (in Hz).
self.loop_rate = rospy.Rate(1)
# Publishers
self.pub = rospy.Publisher('imagetimer', Image,queue_size=10)
# Subscribers
rospy.Subscriber("/camera/image_color",Image,self.callback)
def callback(self, msg):
self.image = self.br.imgmsg_to_cv2(msg)
def start(self):
rospy.loginfo("Timing images")
rospy.spin()
br = CvBridge()
while not rospy.is_shutdown():
rospy.loginfo('publishing image')
#br = CvBridge()
self.pub.publish(br.cv2_to_imgmsg(self.image))
rate.sleep()
if __name__ == '__main__':
rospy.init_node("imagetimer111", anonymous=True)
my_node = Nodo()
my_node.start()
在我的例子中,我发现图像主题有压缩图像。请验证您是否属于这种情况。
我使用以下代码读取 .bag 文件。如果您发现您的 ROS 主题中有压缩图像,您可以使用此代码的部分内容来执行转换
bag = rosbag.Bag(os.path.join(path_to_bags, bag_list[index]))
for topic, msg, t in bag.read_messages(topics=['/conti115/image_raw/compressed']):
try:
img = bridge.compressed_imgmsg_to_cv2(msg)
except CvBridgeError, e:
print e
txt = str(datetime.datetime.fromtimestamp(t.to_sec()))
cv2.rectangle(img, (0, 0), (500, 40), (0,0,0), -1)
cv2.putText(img, txt, (0, 30), 1, 2, (255, 255, 255), 2)
cv2.imshow("win",img)
wtr.write(img)
if cv2.waitKey(5)==27:
cv2.destroyAllWindows()
break
bag.close()
一旦你 运行 rospy.spin()
代码就不会继续。在 rospy 中,一旦你有了 rospy.Subsriber()
行,它就会为回调分离另一个线程。 rospy.spin()
本质上使节点保持活动状态,因此回调并保持运转。
此处您使用 while 循环来保持节点活动,因此不需要 rospy.spin()
。
这个版本应该可以工作:
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import os
import numpy as np
class Nodo(object):
def __init__(self):
# Params
self.image = None
self.br = CvBridge()
# Node cycle rate (in Hz).
self.loop_rate = rospy.Rate(1)
# Publishers
self.pub = rospy.Publisher('imagetimer', Image,queue_size=10)
# Subscribers
rospy.Subscriber("/camera/image_color",Image,self.callback)
def callback(self, msg):
rospy.loginfo('Image received...')
self.image = self.br.imgmsg_to_cv2(msg)
def start(self):
rospy.loginfo("Timing images")
#rospy.spin()
while not rospy.is_shutdown():
rospy.loginfo('publishing image')
#br = CvBridge()
if self.image is not None:
self.pub.publish(br.cv2_to_imgmsg(self.image))
self.loop_rate.sleep()
if __name__ == '__main__':
rospy.init_node("imagetimer111", anonymous=True)
my_node = Nodo()
my_node.start()
我正在尝试订阅“/camera/image_color”主题,该主题是我相机的数据。然后我想在 opencv 中对这些图像做一些巫术,并以特定的频率发布它们。这样我就可以用另一个节点订阅它们。
到目前为止,我已经尝试了以下代码及其许多变体。此时代码什么都不做。没有图像被发布到“/imagetimer”主题。我得到一个输出 "Timing images" 然后没有进一步发生。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import os
import numpy as np
class Nodo(object):
def __init__(self):
# Params
self.image = None
self.br = CvBridge()
# Node cycle rate (in Hz).
self.loop_rate = rospy.Rate(1)
# Publishers
self.pub = rospy.Publisher('imagetimer', Image,queue_size=10)
# Subscribers
rospy.Subscriber("/camera/image_color",Image,self.callback)
def callback(self, msg):
self.image = self.br.imgmsg_to_cv2(msg)
def start(self):
rospy.loginfo("Timing images")
rospy.spin()
br = CvBridge()
while not rospy.is_shutdown():
rospy.loginfo('publishing image')
#br = CvBridge()
self.pub.publish(br.cv2_to_imgmsg(self.image))
rate.sleep()
if __name__ == '__main__':
rospy.init_node("imagetimer111", anonymous=True)
my_node = Nodo()
my_node.start()
在我的例子中,我发现图像主题有压缩图像。请验证您是否属于这种情况。
我使用以下代码读取 .bag 文件。如果您发现您的 ROS 主题中有压缩图像,您可以使用此代码的部分内容来执行转换
bag = rosbag.Bag(os.path.join(path_to_bags, bag_list[index]))
for topic, msg, t in bag.read_messages(topics=['/conti115/image_raw/compressed']):
try:
img = bridge.compressed_imgmsg_to_cv2(msg)
except CvBridgeError, e:
print e
txt = str(datetime.datetime.fromtimestamp(t.to_sec()))
cv2.rectangle(img, (0, 0), (500, 40), (0,0,0), -1)
cv2.putText(img, txt, (0, 30), 1, 2, (255, 255, 255), 2)
cv2.imshow("win",img)
wtr.write(img)
if cv2.waitKey(5)==27:
cv2.destroyAllWindows()
break
bag.close()
一旦你 运行 rospy.spin()
代码就不会继续。在 rospy 中,一旦你有了 rospy.Subsriber()
行,它就会为回调分离另一个线程。 rospy.spin()
本质上使节点保持活动状态,因此回调并保持运转。
此处您使用 while 循环来保持节点活动,因此不需要 rospy.spin()
。
这个版本应该可以工作:
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import os
import numpy as np
class Nodo(object):
def __init__(self):
# Params
self.image = None
self.br = CvBridge()
# Node cycle rate (in Hz).
self.loop_rate = rospy.Rate(1)
# Publishers
self.pub = rospy.Publisher('imagetimer', Image,queue_size=10)
# Subscribers
rospy.Subscriber("/camera/image_color",Image,self.callback)
def callback(self, msg):
rospy.loginfo('Image received...')
self.image = self.br.imgmsg_to_cv2(msg)
def start(self):
rospy.loginfo("Timing images")
#rospy.spin()
while not rospy.is_shutdown():
rospy.loginfo('publishing image')
#br = CvBridge()
if self.image is not None:
self.pub.publish(br.cv2_to_imgmsg(self.image))
self.loop_rate.sleep()
if __name__ == '__main__':
rospy.init_node("imagetimer111", anonymous=True)
my_node = Nodo()
my_node.start()