Python Tkinter 标签删除时的 OpenCV 输出

Python OpenCV output on Tkinter label deletion

我正在尝试删除当前显示由 OpenCV 制作的网络摄像头流的 Tkinter 标签。我最终实现了它,但不是我想要的方式,因为它只是停止了流,但流输出的最后一张图像仍然存在。代码是这样的:

from Tkinter import *
import cv2
from PIL import Image, ImageTk

def Start():
    width, height = 800, 600
    cap = cv2.VideoCapture(0)
    cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, width)
    cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, height)
    def show_frame():
        _, frame = cap.read()
        frame = cv2.flip(frame, 1)
        cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
        img = Image.fromarray(cv2image)
        imgtk = ImageTk.PhotoImage(image=img)
        lmain.imgtk = imgtk
        lmain.configure(image=imgtk)
        lmain.after(10, show_frame)
    show_frame()

root = Tk()
lmain = Label(root)
lmain.pack(side = RIGHT)

Button1 = Button(root, text = "Start", command = Start)
Button1.pack(side = LEFT)
Button2 = Button(root, text = "Stop", command = Start)
Button2.pack(side = LEFT)

root.mainloop()

您可能会注意到我用来停止它的函数与我用来启动它的函数相同,那是因为我对如何停止它一无所知。

我试过你的代码,我在这里添加一些代码:

from Tkinter import *
import cv2
from PIL import Image, ImageTk

isrunning = 0
def Start():
    global isrunning
    if isrunning == 0:
        width, height = 800, 600
        cap = cv2.VideoCapture(0)
        cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, width)
        cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, height)
        isrunning = 1
        lmain.pack(side = RIGHT)

        def show_frame():
            _, frame = cap.read()
            frame = cv2.flip(frame, 1)
            cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
            img = Image.fromarray(cv2image)
            imgtk = ImageTk.PhotoImage(image=img)
            lmain.imgtk = imgtk
            lmain.configure(image=imgtk)
            if isrunning == 1:
                lmain.after(10, show_frame)

    show_frame()

def Stop():
    global isrunning
    isrunning = 0
    lmain.pack_forget()

root = Tk()
lmain = Label(root)

Button1 = Button(root, text = "Start", command = Start)
Button1.pack(side = LEFT)
Button2 = Button(root, text = "Stop", command = Stop)
Button2.pack(side = LEFT)

root.mainloop()

大家可以发现我加了一个全局变量isrunning让函数show_frame每次都检查。如果变量 isrunning 等于 0,函数将停止。我还添加了函数 Stop 作为 "Stop" 按钮的回调函数,其中包含用于删除标签的代码 lmain.pack_forget()

由于每次点击"Stop"按钮都会删除标签,所以我将添加标签的代码移到了Start函数中。希望对你有帮助。

密码是:

from Tkinter import *
import cv2
from PIL import Image, ImageTk

isrunning = 0
def Start():
    global isrunning
    if isrunning == 0:
        global cap
        cap = cv2.VideoCapture(0)
        isrunning = 1
        lmain.pack(side = RIGHT)

        def show_frame():
            _, frame = cap.read()
            frame = cv2.flip(frame, 1)
            cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
            img = Image.fromarray(cv2image)
            imgtk = ImageTk.PhotoImage(image=img)
            lmain.imgtk = imgtk
            lmain.configure(image=imgtk)
            if isrunning == 1:
                lmain.after(10, show_frame)

    show_frame()

def Stop():
    global isrunning
    isrunning = 0
    lmain.pack_forget()

def main():
    Stop()
    Button1.invoke()
    Stop()


root = Tk()
lmain = Label(root)

Button1 = Button(root, text = "Start", command = Start)
Button1.pack(side = LEFT)
Button2 = Button(root, text = "Stop", command = main)
Button2.pack(side = LEFT)

root.mainloop()