Search code examples
pythonopencvros

Cannot get video stream from CompressedImage message


I am committing a newbie mistake somewhere here that I can't seem to figure out. I have the below sample code that does work. The second half is my attempt at getting the video feed from my robot. When launching the code, I get nothing.. not even a window.

#!/usr/bin/env python

import rospy
import cv2
import numpy as np
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image, CompressedImage
import time

class LineFollower(object):

    def __init__(self):

        rospy.logwarn("Init line Follower")
        self.bridge = CvBridge()       
        self.image_sub = rospy.Subscriber('/camera/image_raw/compressed', CompressedImage, self.camera_callback, queue_size = 1)
        time.sleep(5) 

    def camera_callback(self,data):

        try:
            image_np = self.bridge.compressed_imgmsg_to_cv2(data)
        except CvBridgeError as e:
            print(e)

      
        cv2.imshow("Full Img", image_np)

        cv2.waitKey(1)

    
    def clean_up(self):
         cv2.destroyAllWindows()

def main():
    rospy.init_node('line_following_node', anonymous=True)

    line_follower_object = LineFollower()

    rate = rospy.Rate(5) #originally 5
    ctrl_c = False
    def shutdownhook():
        # Works better than the rospy.is_shut_down()
        line_follower_object.clean_up()
        rospy.loginfo("shutdown time!")
        ctrl_c = True

    rospy.on_shutdown(shutdownhook)

    while not ctrl_c:
        rate.sleep()

if __name__ == '__main__':
    main()

The code that I am working on is as follows:

#!/usr/bin/env python
import cv2
import numpy as np
from timeit import default_timer as timer
from std_msgs.msg import Float64
from sensor_msgs.msg import Image, CompressedImage
from cv_bridge import CvBridge, CvBridgeError
import rospy

import sys
print(sys.version)
print(cv2.__version__)

height = 480
width = 640
global_frame = np.zeros((height,width,3), np.uint8)
def calculate_lane_pose(frame):


    # Display the resulting frame
    cv2.imshow('Frame', frame)
  

def camera_callback(self,data):

    try:
        global_frame = self.CvBridge.compressed_imgmsg_to_cv2(data)
    except CvBridgeError as e:
        print(e)

    height, width, channels = global_frame.shape
    print(height)
    cv2.imshow("Original", global_frame)

def lane_pose_publisher():
    # Set the node name
    rospy.init_node('lane_pose_publisher', anonymous=True)

    rospy.Subscriber('/camera/image_raw/compressed', CompressedImage, queue_size = 1)
    # set rate
    rate = rospy.Rate(1000) # 1000hz

    while (1):
        rate.sleep()

        if cv2.waitKey(0) & 0xFF == ord('q'):
            break
    # cap.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    try:
        lane_pose_publisher()
    except rospy.ROSInterruptException:
        pass

Solution

  • Your example code does not set a callback in the call to rospy.Subscriber(). It needs to be defined like this

    #!/usr/bin/env python
    import cv2
    import numpy as np
    from timeit import default_timer as timer
    from std_msgs.msg import Float64
    from sensor_msgs.msg import Image, CompressedImage
    from cv_bridge import CvBridge, CvBridgeError
    import rospy
    
    import sys
    print(sys.version)
    print(cv2.__version__)
    
    height = 480
    width = 640
    global_frame = np.zeros((height,width,3), np.uint8)
    def calculate_lane_pose(frame):
    
    
        # Display the resulting frame
        cv2.imshow('Frame', frame)
      
    
    def camera_callback(data):
    
        bridge = CvBridge() 
    
        try:
            global_frame = bridge.compressed_imgmsg_to_cv2(data)
        except CvBridgeError as e:
            print(e)
    
        height, width, channels = global_frame.shape
        print(height)
        cv2.imshow("Original", global_frame)
    
    def lane_pose_publisher():
        # Set the node name
        rospy.init_node('lane_pose_publisher', anonymous=True)
    
        rospy.Subscriber('/camera/image_raw/compressed', CompressedImage, camera_callback, queue_size = 1)
        # set rate
        rate = rospy.Rate(1000) # 1000hz
    
        while (1):
            rate.sleep()
    
            if cv2.waitKey(0) & 0xFF == ord('q'):
                break
        # cap.release()
        cv2.destroyAllWindows()
    
    
    if __name__ == '__main__':
        try:
            lane_pose_publisher()
        except rospy.ROSInterruptException:
            pass