【问题标题】:Motion Detector GUI运动检测器 GUI
【发布时间】:2021-10-27 23:14:18
【问题描述】:

我一直在尝试使用 tkinter 制作第 29 节中想到的运动检测器应用程序的 GUI,我希望它像,将有 4 个不同的按钮,4 个用于不同的框架,即 Delta 框架,灰度,彩色和阈值框架。 我一直在尝试这个,但是当我这样做时。

按钮起作用,但它显示的帧始终是第一帧,它不会更新。

我的代码:

import tkinter
import cv2, time
from tkinter import *
from tkinter import ttk
 
top = tkinter.Tk()
 
first_frame=None
video=cv2.VideoCapture(0)
 
 
while True:
    check, frame = video.read()
 
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    gray=cv2.GaussianBlur(gray,(21,21),0)
 
    if first_frame is None:
        first_frame=gray
        continue
 
    delta_frame=cv2.absdiff(first_frame,gray)
 
    thresh_delta=cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
 
    thresh_delta=cv2.dilate(thresh_delta, None, iterations=2)
 
    (cnts,_) = cv2.findContours(thresh_delta.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
 
    for countour in cnts:
        if cv2.contourArea(countour) < 1000:
            continue
    
        (x, y, w, h) = cv2.boundingRect(countour)
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 3)    
 
    def Gray():
        cv2.imshow("Gray",gray)
    cv2.imshow("delta frame", delta_frame)
    cv2.imshow("Threshold Delta Frame", thresh_delta)
    cv2.imshow("Color Frame", frame)
 
    Button_Gray= tkinter.Button(top, text="Grayscale", command= Gray)
    Button_Gray.pack()
    top.mainloop()
   
    key=cv2.waitKey(1)
    print(gray)
 
    if key==ord("q"):
        break
 
 
video.realease()
cv2.destroyAllWindows

非常感谢您的快速帮助!

问候 高拉夫·辛格

【问题讨论】:

  • top.mainloop() 永远不会返回,它将永远运行。这就是您的问题的原因。此外,您不应该混合使用 Tkinter 和 OpenCV 的 GUI 功能。选择一个 GUI 或另一个。

标签: python-3.x opencv user-interface tkinter


【解决方案1】:

由于top.mainloop(),您的代码将仅显示第一帧,您需要找到一种方法来单独运行该while循环。

这可能是一个解决方案,但使用 tkinter 线程有时是个坏主意,所以这可能不是最好的解决方案:

import tkinter
import cv2
import threading

show_gray = False
show_colored = False
show_thresh = False
show_delta = False
video=cv2.VideoCapture(0)

def Gray():
    global show_gray
    show_gray = not show_gray

def Colored():
    global show_colored
    show_colored = not show_colored
    
def Delta():
    global show_delta
    show_delta = not show_delta

def Threshold():
    global show_thresh
    show_thresh = not show_thresh

    
def stream_data():
    first_frame=None
    while True:
        check, frame = video.read()
     
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        gray=cv2.GaussianBlur(gray,(21,21),0)
     
        if first_frame is None:
            first_frame=gray
            continue

        delta_frame=cv2.absdiff(first_frame,gray)
     
        thresh_delta=cv2.threshold(delta_frame, 30, 255, cv2.THRESH_BINARY)[1]
     
        thresh_delta=cv2.dilate(thresh_delta, None, iterations=2)
     
        (cnts,_) = cv2.findContours(thresh_delta.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
     
        for countour in cnts:
            if cv2.contourArea(countour) < 1000:
                continue
        
            (x, y, w, h) = cv2.boundingRect(countour)
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 3)    

        if show_gray:
            cv2.imshow("Grayscale frame", gray)
            
        if show_delta:
            cv2.imshow("delta frame", delta_frame)
            
        if show_thresh:
            cv2.imshow("Threshold Delta Frame", thresh_delta)
            
        if show_colored:
            cv2.imshow("Color Frame", frame)
       
        key=cv2.waitKey(1)
        # print(gray)
     
        if key==ord("q"):
            break
        
    video.release()
    cv2.destroyAllWindows()
    exit()
    
def main():
    top = tkinter.Tk()
    Button_Gray= tkinter.Button(top, text="Grayscale", command= Gray)
    Button_Gray.pack()
    colored= tkinter.Button(top, text="Colored", command= Colored)
    colored.pack()
    delta= tkinter.Button(top, text="Delta", command= Delta)
    delta.pack()
    thresh_delta = tkinter.Button(top, text="Threshold", command= Threshold)
    thresh_delta.pack()
    threading.Thread(target = stream_data, daemon = True).start()
    top.mainloop()

main()

另外,您不需要两次导入tkinter,使用wildcard (*) 是个坏主意。

也许这就是你需要的。

我想提一下 Christoph Rackwitz 的评论,混合 cv2 和 tkinter GUI 函数是个坏主意。

【讨论】:

  • 在此,我没有得到预期的结果,我希望它是 4 个按钮,按钮 1 功能:显示灰度按钮 2:显示阈值框架按钮 3:显示增量框架等,在你的答案中有一个按钮使颜色框架变灰,在我的代码中,我有 4 个不同的框架,包括灰度、颜色、增量、阈值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 2013-10-08
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
相关资源
最近更新 更多