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

时间:2018-01-21 12:27:32

标签: python python-2.7 opencv tkinter

我的任务是使用python上的Tkinter在单个GUI上以两个不同的帧显示网络摄像头流及其黑白流。我在谷歌上看过一些例子,但它们的图像不是视频,而是链接在这里。 Example of image display in 2 panes on a single GUI 我需要完全相同的东西,但通过我的网络摄像头实时视频。

3 个答案:

答案 0 :(得分:1)

初步问题:

  

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

最初的问题提到2 windows 所以这里是一个关于如何使用Entry<K,V> before, after; 创建多个窗口的基本示例:

LinkedHashMap<K, V> map = ...

// Get tail as seen before
Entry<K, V> tail = ...

// Preparation for accessing "before" element
Class<?> c = tail.getClass();
Field beforeField = c.getDeclaredField("before");
beforeField.setAccessible(true);

Entry<K, V> entry = tail;
while (entry != null) {
    // Do something with entry
    ...

    // Get next element
    Object beforeValue = beforeField.get(entry);
    entry = (Entry<K, V>) beforeValue;
}

答案 1 :(得分:0)

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()

答案 2 :(得分: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)

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

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

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