运动检测器 GUI
Motion Detector 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
非常感谢快速帮助!
问候
高拉夫·辛格
由于 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 函数是个坏主意。
我一直在尝试使用 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()
,您的代码将仅显示第一帧,您需要找到一种方法 运行 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 函数是个坏主意。