我正在使用opencv在python中实现camshift算法,并使用它给出的位置来移动我的鼠标并在kolour应用程序上绘制。 当我按下tkinter ui上的按钮时,框架会启动然后再启动 按下“q”键后,“框架”不会关闭,框架会冻结,强制退出的选项会出现。我正在使用tkinter for UI。
global paint_open
paint_open = 0
def func():
global frame, roiPts, inputMode ,token
camera = cv2.VideoCapture(0)
cv2.namedWindow("frame")
cv2.setMouseCallback("frame", selectROI)
termination = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)
roiBox = None
li=[]
while True:
(grabbed, frame) = camera.read()
if roiBox is not None:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
backProj = cv2.calcBackProject([hsv], [0], roiHist, [0, 180], 1)
(r, roiBox) = cv2.CamShift(backProj, roiBox, termination)
pts = np.int0(cv2.cv.BoxPoints(r))
li.append(pts)
#coordinates contain the coordinates of the tracked object
coordinates = r[0]
# x, y contains the coordinates
x = int(coordinates[0])
y = int(coordinates[1])
drawing(x,y)
#draws a circle around the center from x,y
cv2.circle(frame, (int(x), int(y)), 4, (0, 0, 255), 2)
#draws a colored frame around the object
cv2.polylines(frame, [pts], True, (255, 0, 0), 2)
#here imshow function start
cv2.imshow("frame", frame)
key = cv2.waitKey(1) & 0xFF
# handle if the 'i' key is pressed, then go into ROI
if key == ord("i") and len(roiPts) < 4:
inputMode = True
orig = frame.copy()
while len(roiPts) < 4:
cv2.imshow("frame", frame)
cv2.waitKey(0)
roiPts = np.array(roiPts)
s = roiPts.sum(axis = 1)
tl = roiPts[np.argmin(s)]
br = roiPts[np.argmax(s)]
roi = orig[tl[1]:br[1], tl[0]:br[0]]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
roiHist = cv2.calcHist([roi], [0], None, [16], [0, 180])
roiHist = cv2.normalize(roiHist, roiHist, 0, 255, cv2.NORM_MINMAX)
roiBox = (tl[0], tl[1], br[0], br[1])
# if the 'q' key is pressed, stop the loop
elif key == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
def drawing(x,y):
global paint_open
if paint_open == 0:
launchapp('kolourpaint')
paint_open = 1
py.dragTo(x,y)
def main():
root=tk.Tk()
bkgcolor='#D84315'
root.configure(background=bkgcolor)
label=tk.Label(root,text="Gesture Recognition Project",font=('arial black',12),fg="white",width=90,height=3,bg="purple")
label.pack()
frame1 = tk.Frame(root,bg=bkgcolor)
frame1.pack(padx=205,pady=25)
bframe1 = tk.Frame(root,bg=bkgcolor)
bframe1.pack(side=tk.BOTTOM,padx=205)
photo3 = tk.PhotoImage(file="3.png")
button2 = tk.Button(frame1, width=255, height=255, image=photo3,text="Slide Presenter",fg="purple",bg="white",command=func)
button2.pack(side=tk.LEFT,padx=25)
button2.image = photo1
# start the event loop
root.mainloop()
答案 0 :(得分:2)
这个问题有点陈旧但值得回答,因为它出现在搜索中。我遇到了同样的问题,最终找到了一个有效的答案。看起来很糟糕,但是允许opencv通过它的进程关闭窗口。 Opencv在waitKey()期间执行其处理,因此在destroyallwindows()函数之前和之后添加一些这样的技巧。
在您的代码中,
cv2.destroyAllWindows()
...试试这个。它对我有用。
# All these waitkeys are a hack to get the OpenCV window to close
cv2.waitKey(1)
cv2.destroyAllWindows()
for i in range (1,5):
cv2.waitKey(1)
return
答案 1 :(得分:1)
我不确定,cv
可能会使用tkinter
来显示窗口,因此root.mainloop()
可能会保持窗口打开。您可以尝试结束root.mainloop()
以关闭程序和所有窗口。
import Tkinter as tk
import cv2
# create global value (with some value)
root = None
def func():
# inform function to use global variable instead of local one
global root
# ...
cv2.destroyAllWindows()
camera.release()
# close root window and leave mainloop()
root.destroy()
def main():
# inform function to use global variable instead of local one
global root
root = tk.Tk()
# ...
root.mainloop()
main()
答案 2 :(得分:1)
由于调用 destroyAllWindows()函数会打开一个新窗口,因此需要按空格键以关闭命令的执行。