Displaying feed from ffmpeg pipe on rqt_image_view
I am using ffmpeg to pipe video feed from an IP camera into stdout, then using cv_bridge to convert each frame into a compressed image message before publishing it and viewing them on rqt_image_view.
import subprocess
import numpy as np
import rospy
from sensor_msgs.msg import CompressedImage
from cv_bridge import CvBridge, CvBridgeError
class IPStream():
def __init__(self):
self.FFMPEG_CMD = "ffmpeg -nostdin -i <rtsp_stream> -pix_fmt bgr24 -r 12 -an -vcodec rawvideo -f rawvideo -".split(" ")
self.WIDTH = 800
self.HEIGHT = 600
self.process = subprocess.Popen(self.FFMPEG_CMD, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
self.bridge = CvBridge()
self.pub = rospy.Publisher('rtsp_feed', CompressedImage, queue_size=10)
def ffmpeg_pipe(self):
while True:
raw_frame = self.process.stdout.read(self.WIDTH*self.HEIGHT*3)
frame = np.frombuffer(raw_frame, np.uint8)
frame = frame.reshape((self.HEIGHT, self.WIDTH, 3))
yield frame
def stream_pub(self):
generate = self.ffmpeg_pipe()
while True:
try:
frame = next(generate)
msg = self.bridge.cv2_to_compressed_imgmsg(frame)
self.pub.publish(msg)
except CvBridgeError as e:
print(str(e))
if __name__ == "__main__":
rospy.init_node("ip_stream")
camera = IPStream()
camera.stream_pub()
try:
rospy.spin()
except KeyboardInterrupt:
camera.process.terminate()
Using rostopic echo /rtsp_feed does provide me with an array, But I am unable to display the compressed image on rqt_image_view. Any idea what is wrong the the above implementation?