python-3.x - 运动检测器 GUI
问题描述
我一直在尝试使用 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
将不胜感激快速帮助!
问候 Gaurav SINGH
解决方案
您的代码将仅显示第一帧,因为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 函数是个坏主意。
推荐阅读
- excel - 如何创建一个新列,它告诉一个值是否唯一包含在另一列中?
- laravel - 如何解决laravel中保存图片的问题
- c# - 从中心点更改窗口尺寸?
- typescript - Testcafe Docker - 错误:TypeScript 编译失败。找不到名称“require”
- python-3.x - 从python3的嵌套数组中的键列表中获取值的优雅方法?
- android - 改造和api,进口问题
- java - 使用 Zerocode 运行 Junit 测试套件
- java - 如何检测 DFA 的错误状态?
- mongodb - 当 mongo 数组具有特定值时省略部分数组
- java - 使用 Rest 模板时不允许接收 405 方法