使用Python在Tkinter中进行GUI设计的多视频显示

问题描述 投票:-3回答:4

[我的任务是使用python上的Tkinter在单个GUI上的两个不同帧中显示网络摄像头流及其黑白流。我在Google上看到了一些示例,但它们的图像不是视频,如此处的链接所示。Example of image display in 2 panes on a single GUI我需要完全一样的东西,但需要通过网络摄像头进行实时录像。

python python-2.7 opencv tkinter
4个回答
1
投票

初始问题:

“我在使用python中的Tkinter在GUI中显示多个(2)窗口来显示视频帧时遇到问题。请帮助我此任务的代码。“

最初的问题提到2 windows,所以这是一个有关如何使用tkinter创建多个窗口的基本示例:

#import tkinter as tk
import Tkinter as tk


class MainWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        #super().__init__()
        tk.Tk.__init__(self)

        self.title("This is the MainWindow")
        self._is_hidden = False
        self.window1 = OtherWindow(self, title="window 1")
        self.window2 = OtherWindow(self, title="window 2")


    def toggle_hide(self):
        if self._is_hidden:
            self.iconify()
            self.deiconify()
        else:
            self.withdraw()

        self._is_hidden = not self._is_hidden

class OtherWindow(tk.Toplevel):
    def __init__(self, master, *args, **kwargs):
        #super().__init__(master)
        tk.Toplevel.__init__(self, master)

        if 'title' in kwargs:
            self.title(kwargs['title'])

        self.hide_main_button = tk.Button(self, text="Hide/Show MainWindow")
        self.hide_main_button['command'] = self.master.toggle_hide
        self.hide_main_button.pack()


if __name__ == '__main__':
    root = MainWindow()
    root.mainloop()

1
投票
from ttk import *
import Tkinter as tk
from Tkinter import *
import cv2
from PIL import Image, ImageTk
import os
import numpy as np


global last_frame                                      #creating global              variable
last_frame = np.zeros((480, 640, 3), dtype=np.uint8)
global last_frame2                                      #creating global      variable
last_frame2 = np.zeros((480, 640, 3), dtype=np.uint8)
global cap
cap = cv2.VideoCapture(1)

def show_vid():                                        #creating a function
    if not cap.isOpened():                             #checks for the opening of camera
    print("cant open the camera")
    flag, frame = cap.read()
    frame = cv2.resize(frame,(400,500))
    if flag is None:
    print "Major error!"
    elif flag:
    global last_frame
    last_frame = frame.copy()
    global last_frame2
    last_frame2 = frame.copy()

pic = cv2.cvtColor(last_frame, cv2.COLOR_BGR2RGB)     #we can change the display color of the frame gray,black&white here
img = Image.fromarray(pic)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_vid)


def show_vid2():
pic2 = cv2.cvtColor(last_frame2, cv2.COLOR_BGR2GRAY)
img2 = Image.fromarray(pic2)
img2tk = ImageTk.PhotoImage(image=img2)
lmain2.img2tk = img2tk
lmain2.configure(image=img2tk)
lmain2.after(10, show_vid2)

if __name__ == '__main__':
root=tk.Tk()                                     #assigning root variable        for Tkinter as tk
lmain = tk.Label(master=root)
lmain2 = tk.Label(master=root)
#lmain.Frame= Frame(width=768, height=576)
#framex.grid(column=3,rowspan=2,padx=5, pady=5)
lmain.pack(side = LEFT)
lmain2.pack(side = RIGHT)
root.title("Fire Alarm Detector")            #you can give any title
root.geometry("900x700+100+10") #size of window , x-axis, yaxis
exitbutton = Button(root, text='Quit',fg="red",command=   root.destroy).pack(side = BOTTOM,)
show_vid()
show_vid2()
root.mainloop()                                  #keeps the application in an infinite loop so it works continuosly
cap.release()

0
投票
import tkinter
import PIL.Image
import PIL.ImageTk
import cv2


class App:
    def __init__(self, window, video_source1, video_source2):
        self.window = window
        self.window.title("KEC MEDIA PLAYER")
        self.video_source1 = video_source1
        self.video_source2 = video_source2
        self.photo1 = ""
        self.photo2 = ""

        # open video source
        self.vid1 = MyVideoCapture(self.video_source1, self.video_source2)

        # Create a canvas that can fit the above video source size
        self.canvas1 = tkinter.Canvas(window, width=500, height=500)
        self.canvas2 = tkinter.Canvas(window, width=500, height=500)
        self.canvas1.pack(padx=5, pady=10, side="left")
        self.canvas2.pack(padx=5, pady=60, side="left")

        # After it is called once, the update method will be automatically called every delay milliseconds
        self.delay = 15
        self.update()

        self.window.mainloop()

    def update(self):
        # Get a frame from the video source
        ret1, frame1, ret2, frame2 = self.vid1.get_frame

        if ret1 and ret2:
                self.photo1 = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame1))
                self.photo2 = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame2))
                self.canvas1.create_image(0, 0, image=self.photo1, anchor=tkinter.NW)
                self.canvas2.create_image(0, 0, image=self.photo2, anchor=tkinter.NW)

        self.window.after(self.delay, self.update)


class MyVideoCapture:
    def __init__(self, video_source1, video_source2):
        # Open the video source
        self.vid1 = cv2.VideoCapture(video_source1)
        self.vid2 = cv2.VideoCapture(video_source2)

        if not self.vid1.isOpened():
            raise ValueError("Unable to open video source", video_source1)

    @property
    def get_frame(self):
        ret1 = ""
        ret2 = ""
        if self.vid1.isOpened() and self.vid2.isOpened():
            ret1, frame1 = self.vid1.read()
            ret2, frame2 = self.vid2.read()
            frame1 = cv2.resize(frame1, (500, 500))
            frame2 = cv2.resize(frame2, (500, 500))
            if ret1 and ret2:
                # Return a boolean success flag and the current frame converted to BGR
                return ret1, cv2.cvtColor(frame1, cv2.COLOR_BGR2RGB), ret2, cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
            else:
                return ret1, None, ret2, None
        else:
            return ret1, None, ret2, None

    # Release the video source when the object is destroyed
    def __del__(self):
        if self.vid1.isOpened():
            self.vid1.release()
        if self.vid2.isOpened():
            self.vid2.release()


def callback():
    global v1,v2
    v1=E1.get()
    v2=E2.get()
    if v1 == "" or v2 == "":
        L3.pack()
        return
    initial.destroy()


v1 = ""
v2 = ""

initial = tkinter.Tk()
initial.title("KEC MEDIA PLAYER")
L0 = tkinter.Label(initial, text="Enter the full path")
L0.pack()
L1 = tkinter.Label(initial, text="Video 1")
L1.pack()
E1 = tkinter.Entry(initial, bd =5)
E1.pack()
L2 = tkinter.Label(initial, text="Video 2")
L2.pack()
E2 = tkinter.Entry(initial, bd =5)
E2.pack()
B = tkinter.Button(initial, text ="Next", command = callback)
B.pack()
L3 = tkinter.Label(initial, text="Enter both the names")

initial.mainloop()


# Create a window and pass it to the Application object
App(tkinter.Tk(),v1, v2)

此代码在正常情况下有效,但是我还没有处理一个视频结束而另一个仍在播放的情况。另外,此代码未处理音频。

我在同一窗口中创建了两个画布,并将视频作为一系列图像运行。我已经调整了视频的大小以适合恒定的画布大小,但是您可以根据需要更改画布的大小以适合视频。

您可以将源更改为来自网络摄像头。


0
投票

大家好,我遇到了一些问题,我正在使用Tkinter创建一个GUI,我的第一页有两个按钮,它们都与直播单摄像头链接在一起。但是当我关闭第一个实时流窗口时,相机无法释放。有人帮我吗?

© www.soinside.com 2019 - 2024. All rights reserved.