带Tkinter的OpenCV:滞后和窗口问题

时间:2020-01-14 19:25:47

标签: python opencv tkinter

我最近开始在tkinter中使用opencv,并且开始遇到一些我似乎无法自行解决的问题... 下面的代码应该在播放视频文件的同时能够选择要在哪个子目录中进行分类。我开始遇到的问题是,每秒的帧数似乎很奇怪,因为有些剪辑我播放似乎“滞后”,或者没有正确的fps。 其次,该代码看起来确实很凌乱,因此单击一下按钮后按钮“消失了”。 最后,我尝试做一些事情,使按钮尽可能大,以填充窗口底部的x轴,而播放视频的主框架保持相同的大小(因此,视频应该停留在中间,在不改变比率的情况下将他的身高和宽度调整为框架大小),但这似乎也不起作用。

任何帮助将不胜感激

PS:我正在将Python 3.8与openCV 4.1.2一起使用

这是代码:

from tkinter import Tk, Button, Label, Frame
import os
import shutil
import cv2
from PIL import Image, ImageTk

x = 0

path = "path/to/folder"

def nbr():
    global x
    x += 1
    text.config(text=files[x])

class ButtonX (Button):

    def __init__ (self, *args, folder="", **kwargs):
        super().__init__(*args, **kwargs)
        self.folder = folder
        self.config(command=self.moveTo)

    def moveTo(self):
        global x
        global cap
        global width
        if cap.isOpened():
            cap.release()
        shutil.move(path + files[x], path + self.folder + "/" +files[x])
        print(files[x] + " moved to " + self.folder)
        nbr()
        cap = cv2.VideoCapture(path+files[x])
        ret, frame = cap.read()
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

folders = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path,dI))]

allfiles = os.listdir(path)

files = [ fname for fname in allfiles if fname.endswith('.webm')]
files.sort(key=len)

print(folders)

window = Tk()
window.resizable(0, 0)
window.geometry("1600x908")
back = Frame(window)
back.grid(row=1, column=1)
window.grid_rowconfigure(0, weight=1)
window.grid_rowconfigure(2, weight=1)
window.grid_columnconfigure(0, weight=1)
window.grid_columnconfigure(2, weight=1)
player = Frame(back)
player.grid(row = 0, column=0)
buttouns = Frame(back)
buttouns.grid(row = 1, column=0)

text = Label(player)
text.grid(row=0, columnspan=4, sticky='w,e,n,s', padx=5, pady=50)

cap = cv2.VideoCapture(path+files[x])
fps = cap.get(cv2.CAP_PROP_FPS)
cap.set(cv2.CAP_PROP_FPS, fps)
print(fps)
height = 600
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

def show_frame():
    global cap
    global width
    cap.set(cv2.CAP_PROP_FPS, fps)
    ret, frame = cap.read()

    if frame is None:

        cap = cv2.VideoCapture(path+files[x])
        ret, frame = cap.read()

    cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)

    img = Image.fromarray(cv2image).resize((width, height))
    imgtk = ImageTk.PhotoImage(image = img)
    text.imgtk = imgtk
    text.configure(image=imgtk)
    text.after(3, show_frame)

buttons = []

z = 1
y = 0

for i in range(len(folders)):
    new_button = ButtonX(buttouns,text=folders[i], width=20, height=2, folder=folders[i])
    buttons.append(new_button)
    buttons[i].grid(row=z, column=y, sticky='w,e,n,s', padx=5, pady=5)

    y += 1
    if y == 4:
        y = 0
        z += 1

def deleted():
    global cap
    global width
    print("deleted " + files[x])
    if cap.isOpened():
        cap.release()
    shutil.move(path + files[x], "path/to/deleted" + files[x])
    nbr()
    cap = cv2.VideoCapture(path+files[x])
    ret, frame = cap.read()
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

def skipped():
    global cap
    global width
    print(files[x] + " skipped")
    if cap.isOpened():
        cap.release()
    nbr()
    cap = cv2.VideoCapture(path+files[x])
    ret, frame = cap.read()
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)*(height/cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

delete= Button(buttouns,text="Delete", width=20, height=2, command=deleted, foreground="red")
delete.grid(row=z+1,column=2, columnspan=2, sticky='w,e,n,s', padx=5, pady=5)
skip= Button(buttouns,text="Skip", width=20, height=2, command=skipped)
skip.grid(row=z+1, columnspan=2, sticky='w,e,n,s', padx=5, pady=5)

show_frame()
window.mainloop()

0 个答案:

没有答案