Как подписаться и опубликовать изображения в ROS

#python #opencv #ros

#python #opencv #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()

  

Комментарии:

1. В этом вопросе отсутствует ваша проблема — что именно не работает?

2. прошу прощения, это была плохая оплошность, я добавил это.

Ответ №1:

После запуска 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(self.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()
  

Комментарии:

1. Пожалуйста, «примите» ответ, если он решил вашу проблему.

Ответ №2:

В моем случае я обнаружил, что в разделе image были сжатые изображения. Пожалуйста, проверьте, подходит ли это для вас.

Я использовал следующий код для чтения из файлов .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()