Ask Your Question
1

Trying to publish each frame of video as Image

asked 2017-07-12 08:45:43 -0500

robocop gravatar image

updated 2017-07-13 11:09:50 -0500

lucasw gravatar image

I have made a node that either starts a webcam or takes a video file and plays it and (is meant to) publish each frame of the video to a topic so it can be processed by other nodes. However for a 14 second long video with 20 frames per second I am only getting 36 images published. I don't know why I am missing so many of the images. Here is my code

#!/usr/bin/env python


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



def image_publisher():

    pub = rospy.Publisher('camera_image', Image, queue_size=100)
    #if pub != None:
        #print "pub created"
    rospy.init_node('image_publisher', anonymous=True)
    #rate = rospy.Rate(10) # not sure this is necessary
    bridge = CvBridge()


    if len(sys.argv) < 2:
        print "You must give an argument to open a video stream."
        print "  It can be a number as video device, e.g.: 0 would be /dev/video0"
        print "  It can be a url of a stream,        e.g.: rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"
        print "  It can be a video file,             e.g.: robotvideo.mkv"
        exit(0)

    resource = sys.argv[1]
    # If we are given just a number, interpret it as a video device
    if len(resource) < 3:
        resource_name = "/dev/video" + resource
        resource = int(resource)
        vidfile = False
    else:
        resource_name = resource
        vidfile = True
    print "Trying to open resource: " + resource_name
    cap = cv2.VideoCapture(resource)
    if not cap.isOpened():
        print "Error opening resource: " + str(resource)
        print "Maybe opencv VideoCapture can't open it"
        exit(0)


    print "Correctly opened resource, starting to show feed."
    rval, frame = cap.read()
    while rval:
        cv2.imshow("Stream: " + resource_name, frame)
        rval, frame = cap.read()

        # ROS image stuff
        if vidfile and frame is not None:
            frame = np.uint8(frame)
        image_message = bridge.cv2_to_imgmsg(frame, encoding="passthrough")
        #if image_message != None:
            #print "There's something here"
        #rospy.loginfo(image_message)


        pub.publish(image_message)



        key = cv2.waitKey(50)   # was 20 but playing video fiels too fast
        # print "key pressed: " + str(key)
        # exit on ESC, you may want to uncomment the print to know which key is ESC for you
        if key == 27 or key == 1048603:
            break
    cv2.destroyWindow("preview")




if __name__ == '__main__':
    try:
        image_publisher()
    except rospy.ROSInterruptException:
        pass
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-07-13 07:07:55 -0500

robocop gravatar image

Managed to find a solution:

By adding rate = rospy.Rate(0.5) # Make publishing rate once every 2 seconds (0.5Hz) and changing key = cv2.waitKey(1000) to introduced a delay of 1000 miliseconds, there was enough of a delay for each frame to be published and none to be missed.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-07-12 08:45:43 -0500

Seen: 2,762 times

Last updated: Jul 13 '17