简体   繁体   中英

Stream RTSP Video to Tkinter Frame using OpenCV

I have some IP cameras that provide RTSP video feed, and I know that OpenCV can display the video on its own cv2.imshow() function on a window by using cv2.videoCapture() and something like cap.read() . Now I'm trying to display that video onto a TKinter GUI window. What I have below is the RTSP sample code from the OpenCV website that works very well on an independent window:

import cv2
cap = cv2.VideoCapture('rtsp://192.168.0.169:554/mpeg4')
while True:
    ret, img = cap.read()
    if ret == True:  #lines below may not be necessary
        cv2.imshow('video output', img)
        k = cv2.waitKey(10)& 0xff
        if k == 27:
            break
cap.release()
cv2.destroyAllWindows()

How can I apply the video feed to a TKinter.Frame() or something similar? Also, I will be using a total of 3 cameras on the same interface window, and adding buttons to switch a camera feed to a different TKinter.Frame() .

Thank you in advance!

I managed to get displayed an rtsp stream from my Ip cam to a Tkinter GUI using PIL ImageTk. Although it is a bit laggy on my system due to bad encoding i think. I would advise you to run the processing with cv2.VideoCapture on different thread, because it sometimes frezzes the GUI.

import tkinter as tk 

import cv2  
from PIL import Image
from PIL import ImageTk
import threading
import os

class MainWindow():
    def __init__(self, window, cap):
        self.window = window
        self.cap = cap
        self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)
        self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        self.interval = 10 # Interval in ms to get the latest frame
        # Create canvas for image
        self.canvas = tk.Canvas(self.window, width=600, height=400)
        self.canvas.grid(row=0, column=0)
        # Update image on canvas
        root.after(self.interval, self.update_image)
        self.button = tk.Button()

    def update_image(self):    
        # Get the latest frame and convert image format
        self.OGimage = cv2.cvtColor(self.cap.read()[1], cv2.COLOR_BGR2RGB) # to RGB
        self.OGimage = Image.fromarray(self.OGimage) # to PIL format
        self.image = self.OGimage.resize((600, 400), Image.ANTIALIAS)
        self.image = ImageTk.PhotoImage(self.image) # to ImageTk format
        # Update image
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.image)
        # Repeat every 'interval' ms
        self.window.after(self.interval, self.update_image)

#def run_decoding(): 
    #os.system("ffmpeg -i rtsp://192.168.1.10?tcp -codec copy -f mpegts udp://127.0.0.1:5000 &")


if __name__ == "__main__":
    #my_cam = ONVIFCamera('192.168.1.10', 80, 'gemer.daniel@gmail.com', 'dg24111998')
    #media = my_cam.create_media_service()
    #ptz = my_cam.create_ptz_service()
    #media_profile = media.GetProfiles()[0]

    # Get PTZ configuration options for getting continuous move range
    #request = ptz.create_type('GetConfigurationOptions')
    #request.ConfigurationToken = media_profile.token
    #ptz_configuration_options = ptz.GetConfigurationOptions(request)

    #request = ptz.create_type('ContinuousMove')
    #request.ProfileToken = media_profile._token

    #ptz.Stop({'ProfileToken': media_profile._token})
    #p1 = threading.Thread(target=run_decoding)
    #p1.start()
    root = tk.Tk()
    MainWindow(root, cv2.VideoCapture("rtsp://192.168.1.10?tcp"))
    root.mainloop()

Also, if you constrained using Tkinted you could try the PyQT5 library, i had better results in processing the frames.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM