在Mac上使用Python和OpenCV时,DestroyWindow无法关闭窗口
我的程序用下面的代码生成了一系列窗口:
def display(img, name, fun):
global clicked
cv.NamedWindow(name, 1)
cv.ShowImage(name, img)
cv.SetMouseCallback(name, fun, img)
while cv.WaitKey(33) == -1:
if clicked == 1:
clicked = 0
cv.ShowImage(name, img)
cv.DestroyWindow(name)
我在图形界面窗口里按“q”键想要关闭它。但是,代码还是继续执行,接着又调用了显示函数,结果又显示了第二个图形界面窗口,而第一个窗口却没有关闭。我是在Mac上使用OpenCV 2.1,通过终端运行这个程序的。请问我该怎么关闭这些图形界面窗口呢?谢谢。
16 个回答
Sayem2603
我试了你的解决方案,结果成功了,感谢你!我做了一些尝试和错误,发现循环4次就能解决我的问题……或者把同样的代码发4次也一样有效。
接着,我深入研究了一下:
cv2.destroyAllWindows()
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
cv2.waitKey(1)
或者简单地调用DestroyAllWindows,然后把waitKey()的代码循环4次:
cv2.destroyAllWindows()
for i in range (1,5):
cv2.waitKey(1)
这样也有效。不过我不太懂为什么这样有效,我猜可能和循环代码时产生的中断和延迟有关?
Matthäus Brandl在上面提到,第三次waitKey()对他有效,所以可能在不同的系统上表现会有点不同?(我在用Linux Mint,内核是3.16.1,Python版本是2.7)
单纯的延迟并不能解释这个问题,因为仅仅增加waitKey()的延迟时间并没有解决问题。(我还尝试把print("Hello")循环打印1000次,而不是用waitKey(),只是想看看延迟是否有帮助——结果并没有。)这一定和waitKey()如何与窗口事件互动有关。
OpenCV文档上说:"这个函数是HighGUI中唯一可以获取和处理事件的方法,所以需要定期调用以正常处理事件,除非HighGUI在一个能处理事件的环境中使用。"
也许它在GUI显示中产生了一种中断,让destroyAllWindows()的操作得以执行?
J
你需要在打开窗口后运行 cv.startWindowThread()
。我之前也遇到过这个问题,现在这样做对我有效。
希望这对未来的读者有帮助。另外,还有一个 cv2
的绑定(我建议使用这个,而不是 cv
)。
这段代码对我有效:
import cv2 as cv
import time
WINDOW_NAME = "win"
image = cv.imread("ela.jpg", cv.CV_LOAD_IMAGE_COLOR)
cv.namedWindow(WINDOW_NAME, cv.CV_WINDOW_AUTOSIZE)
initialtime = time.time()
cv.startWindowThread()
while (time.time() - initialtime < 5):
print "in first while"
cv.imshow(WINDOW_NAME, image)
cv.waitKey(1000)
cv.waitKey(1)
cv.destroyAllWindows()
cv.waitKey(1)
initialtime = time.time()
while (time.time() - initialtime < 6):
print "in second while"
在Linux上,C++版本也会出现同样的问题:尝试关闭OpenCV窗口没有效果
在OpenCV的图形界面(GUI)中,有一些特别的地方需要注意。比如,destroyImage
这个函数在Linux系统下(因为在2.1.0之前,默认使用的是Gtk+)不会关闭窗口,除非你先调用了waitKey
来处理事件。你可以在destroyWindow
后面加一个waitKey(1)
,这样可能会有效果。
不过,即使这样,关闭窗口也不一定能成功;因为waitKey
这个函数只有在窗口有焦点的时候才会被执行。如果在你调用destroyWindow
的时候,窗口没有焦点,那么它可能会一直显示,直到你下次再调用destroyWindow
。
我猜这可能是Gtk+的特性;在我使用Windows的时候,这个函数就没有出现过问题。