#python-3.x #opencv #user-interface #tkinter
Вопрос:
Я пытался создать графический интерфейс приложения детектора движения, описанного в разделе 29, с помощью tkinter, я хочу, чтобы было похоже, что будет 4 разных кнопки, 4, функционирующих для различного кадра, который представляет собой дельта-кадр, оттенки серого, цветной и пороговый кадр. Я пытался это сделать, но когда я это делаю.
Кнопка функционирует, но кадр, который она показывает, всегда является первым кадром, он не обновляется.
Мой код:
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
Буду признателен за быструю помощь!
С уважением Гаурав СИНГХ
Комментарии:
1.
top.mainloop()
никогда не вернется, это будет продолжаться вечно. в этом причина вашей проблемы. кроме того, вы не должны смешивать функции графического интерфейса Tkinter и OpenCV. выберите один графический интерфейс или другой.
Ответ №1:
Ваш код покажет только первый кадр , потому top.mainloop()
что вам нужно найти способ запустить этот цикл отдельно.
Это может быть решением, но использование потоков с 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
( * ) — плохая идея.
Может быть, это то, что вам нужно.
Я хочу упомянуть комментарий Кристофа Раквица: смешивать функции графического интерфейса cv2 и tkinter — плохая идея.
Комментарии:
1. В этом случае я не получаю желаемых результатов, я хочу, чтобы это было как 4 кнопки, кнопка 1 функция: Показать оттенки серого кнопка 2: показать пороговую рамку кнопка 3: показать дельта-рамку и т. Д. В вашем ответе есть одна кнопка, которая делает цветовую рамку серой, в моем коде у меня есть 4 разных кадра, включая оттенки серого, цвет, дельта, порог.