Reputation: 61
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!
Upvotes: 0
Views: 2530
Reputation: 124
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, '[email protected]', '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.
Upvotes: 2