DestroyWindow没有使用Python和OpenCV关闭Mac上的窗口

时间:2011-05-24 20:38:30

标签: python user-interface opencv

我的程序使用以下代码生成一系列窗口:<​​/ p>

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)

我在gui窗口内按“q”关闭它。但是,代码继续下一次调用显示功能并显示第二个gui窗口而不关闭第一个窗口。我正在使用带有OpenCV 2.1的Mac,在终端中运行该程序。我该怎么关闭gui窗户?感谢。

12 个答案:

答案 0 :(得分:27)

打开窗口后需要运行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 ++版本也会出现同样的问题: Trying to close OpenCV window has no effect

答案 1 :(得分:20)

OpenCV中的GUI有一些特点。 destroyImage调用无法关闭窗口(至少在Linux下,默认后端为Gtk +直到2.1.0),除非调用waitKey来抽取事件。在waitKey(1)之后立即添加destroyWindow电话可能会有效。

即便如此,也不能保证结束; waitKey函数仅在窗口具有焦点时被截获,因此如果窗口在您调用destroyWindow时没有焦点,则可能会在下一个{{1}之前保持可见状态1}}来电。

我认为这是一种源于Gtk +的行为;当我在Windows下使用它时,该功能没有给我带来任何麻烦。

答案 2 :(得分: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äusBrandl上面说过,第三个waitKey()为他工作,所以每个系统可能略有不同? (我使用3.16.1内核和python 2.7运行Linux Mint)

单独的延迟并没有解释它,因为简单地增加waitKey()的延迟时间并不能解决问题。 (也是循环打印(“Hello”)1000次而不是使用wiatKey()只是为了查看创建的延迟是否有帮助 - 它没有。)必须与waitKey()如何与窗口事件交互更多的事情。 / p>

OpenCV Docs说:“此函数是HighGUI中唯一可以获取和处理事件的方法,因此需要定期调用它以进行正常事件处理,除非在负责事件处理的环境中使用HighGUI 。“

也许它会在GUI显示中创建一个允许destroyAllWindows()动作处理的中断?

Ĵ

答案 3 :(得分:4)

此解决方案适用于我(在Ubuntu 12.04下,在shell中打开python):

在窗口被“销毁”后重新调用cv.ShowImage

答案 4 :(得分:3)

我通过在for循环中调用cv2.waitKey(1)解决了这个问题,我不知道为什么它可以工作但完成了我的工作,所以我没有进一步打扰自己。

for i in range(1,10):
    cv2.destroyAllWindows()
    cv2.waitkey(1)

欢迎您解释。

答案 5 :(得分:2)

如果您使用的是Spyder(Anaconda Package)则存在问题。

这些解决方案都不适合我。 我发现问题不是功能,而是Spyder的一个问题。尝试使用短信并在终端上运行,你可以使用简单的方法:

WINDOW_NAME = "win"
image = cv.imread("foto.jpg", 0)
cv.namedWindow(WINDOW_NAME, cv.CV_WINDOW_AUTOSIZE)

cv.startWindowThread()

cv.imshow(WINDOW_NAME, image)
cv.waitKey()
cv.destroyAllWindows()

答案 6 :(得分:2)

这对我有用:

cv2.namedWindow("image")
cv2.imshow('image', img)
cv2.waitKey(0) # close window when a key press is detected
cv2.destroyWindow('image')
cv2.waitKey(1)

答案 7 :(得分:1)

在python控制台中摆弄这个问题我发现了以下行为:

  • cv2.imshow 之后发出cv2.destroyWindow有时关闭窗口。虽然旧的窗口会在下一次highgui来电时再次弹出,例如cv2.namedWindow
  • 每次尝试cv2.waitKey关闭窗口后,cv2.destroyWindow第三次来电。此外,即使之后使用cv2.namedWindow
  • ,关闭的窗口仍然关闭

希望这有助于某人。

(我使用的是Ubuntu 12.10和python 2.7.3,但是使用了13.04 repos的OpenCV 2.4.2)

答案 8 :(得分:1)

搜索了一段时间之后,所提供的解决方案都没有为我工作,所以由于此功能存在错误而我没有时间修复它,我没有必要使用cv2窗口来显示帧。保存几帧后,您可以在不同的查看器中打开该文件,如VLC或MoviePlayer(适用于Linux)。

这就是我如何做到的。

 import cv2

 threadDie = True # change this to false elsewhere to stop getting the video
 def getVideo(Message):
          print Message
          print "Opening url"
          video = cv2.VideoCapture("rtsp://username:passwordp@IpAddress:554/axis-media/media.amp")

          print "Opened url"
          fourcc = cv2.cv.CV_FOURCC('X','V','I','D')
          fps = 25.0 # or 30.0 for a better quality stream
          writer = cv2.VideoWriter('out.avi', fourcc,fps, (640,480),1)
          i = 0

          print "Reading frames "
          while threadDie:
                  ret, img = video.read()
                  print "frame number: ",i
                  i=i+1
                  writer.write(img)
          del(video)


          print "Finished capturing video"

然后用另一个查看器打开文件,可以在另一个函数中打开,就像你喜欢vlc一样,你可以启动它并将保存的文件作为参数传递。在终端上,我会这样做

vlc out.avi #out.avi is my video file being saved by the function above.

这对我在arch linux上很有用。

答案 9 :(得分:1)

我有同样的问题。问题是while(cap.isOpened()):循环未完成,因此我添加了以下结构。如果视频在以下部分中没有帧,则它将ret值返回为False。通常,我将destroyAllWindows命令置于循环外,但将其移入了循环。它在我的代码中正常工作。

while(cap.isOpened()):
 ret, frame = cap.read()  
 if ret == False:
        cap.release()
        cv2.waitKey(1)
        cv2.destroyAllWindows()
        cv2.waitKey(1)

答案 10 :(得分:0)

如果我在Jupyter Notebook上运行上述解决方案,那么上述解决方案似乎都不对我起作用(关闭时窗口会挂起,您需要强制退出Python才能关闭窗口)。

我正在使用macOS High Sierra 10.13.4,Python 3.6.5,OpenCV 3.4.1。

如果您将其作为.py文件运行,则以下代码有效(源:https://www.learnopencv.com/read-write-and-display-a-video-using-opencv-cpp-python/)。它会打开相机,记录视频,按“ q”键成功关闭窗口,然后将视频保存为.avi格式。

page := length / pagesize
if length % pagesize > 0 {
    page++
}

答案 11 :(得分:0)

这在spyder中对我有用:

import cv2 as cv
cv.namedWindow("image")
img = cv.imread("image_name.jpg")
cv.imshow("image",img)

cv.waitKey(5000) # 5 sec delay before image window closes
cv.destroyWindow("image")

记住,仅使用cv.waitKey(positive Integer)可以正常工作