繁体   English   中英

DestroyWindow 不会在 Mac 上使用 Python 和 OpenCV 关闭 window

[英]DestroyWindow does not close window on Mac using Python and OpenCV

我的程序使用以下代码生成一系列 windows:

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 window 中按“q”来关闭它。 但是,代码继续到显示 function 的下一个调用,并显示第二个 gui window 而没有关闭第一个。 我正在使用带有 OpenCV 2.1 的 Mac,在终端中运行程序。 如何关闭 gui windows? 谢谢。

打开 window 后需要运行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 Z05B8C11 效果352762FBF24C

OpenCV 中的 GUI 有一些特点。 除非waitKey来泵送事件,否则destroyImage调用无法关闭 window(至少在 Linux 下,其中默认后端是 Gtk+ 直到 2.1.0)。 在 destroyWindow 之后添加destroyWindow waitKey(1)调用可能会起作用。

即便如此,也不能保证关闭; 只有当 window 有焦点时, waitKey function 才会被拦截,因此如果 window 在您调用destroyWindow调用时没有焦点,直到调用 destroyWindow 为止, destroyWindow可能。

我假设这是源于 Gtk+ 的行为; function 在 Windows 下使用时没有给我带来任何麻烦。

赛耶姆2603

我尝试了您的解决方案,它对我有用 - 谢谢。 我做了一些试验和错误,发现循环 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 kernel 和 python 2.7)

单独的延迟并不能解释它,因为简单地增加 waitKey() 的延迟时间并不能解决问题。 (还循环 print("Hello") 1000 次,而不是使用 wiatKey() 只是为了查看创建的延迟是否有帮助 - 它没有。)必须与 waitKey() 如何与 window 事件交互有关。

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

也许它会在允许处理 destroyAllWindows() 操作的 GUI 显示中创建某种中断?

Ĵ

这对我有用:

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

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

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

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

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

欢迎您解释。

如果您使用的是 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()

如果我在 Jupyter Notebook 上运行上述解决方案,似乎没有一个对我有用(关闭时 window 挂起,您需要强制退出 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'成功关闭window,并将视频保存为.avi格式。

import cv2
import numpy as np

# Create a VideoCapture object
cap = cv2.VideoCapture(0)

# Check if camera opened successfully
if (cap.isOpened() == False): 
  print("Unable to read camera feed")

# Default resolutions of the frame are obtained.The default resolutions are system dependent.
# We convert the resolutions from float to integer.
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

# Define the codec and create VideoWriter object.The output is stored in 'outpy.avi' file.
out = cv2.VideoWriter('outpy.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))

while(True):
  ret, frame = cap.read()

  if ret == True: 

    # Write the frame into the file 'output.avi'
    out.write(frame)

    # Display the resulting frame    
    cv2.imshow('frame',frame)

    # Press Q on keyboard to stop recording
    if cv2.waitKey(1) & 0xFF == ord('q'):
      break

  # Break the loop
  else:
    break 

# When everything done, release the video capture and video write objects
cap.release()
out.release()

# Closes all the frames
cv2.destroyAllWindows() 

在 python 控制台中摆弄这个问题,我观察到以下行为:

  • cv2.imshow之后发出cv2.destroyWindow有时会关闭 window。 尽管旧的 window 会在下一个highgui调用中再次弹出,例如cv2.namedWindow
  • cv2.destroyWindow每次尝试关闭cv2.waitKey之后,第三次调用 cv2.waitKey 。 此外,关闭的 window 保持关闭状态,即使之后使用cv2.namedWindow

希望这可以帮助某人。

(我使用 Ubuntu 12.10 和 python 2.7.3 但 OpenCV 2.4.2 来自 13.04 repos)

在搜索了一段时间后,提供的解决方案都没有为我工作,所以因为这个 function 中有一个错误,我没有时间修复它,我不必使用 cv2 window 来显示帧。 保存几帧后,您可以在其他查看器中打开文件,例如 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"

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

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

这在 linux 上对我有用。

我遇到过同样的问题。 问题是 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)

这在 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)才能正常工作

cv2.imshow("the image I want to show ",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)  # to close the window.

上面的代码对我来说效果很好。 我正在使用 Mac 和 python 3.7。

关闭终端,稍后关闭 window,它在 Windows 的 Visual Studio Code 中为我工作; 我做了一个任务来编译并在终端中运行可执行文件,该程序使用我的网络摄像头捕获视频并将其显示在 QT window 中,当我单击关闭按钮时它没有关闭,它再次重新打开并继续程序,直到我关闭终端,然后可以关闭程序 window 而不会再次重新打开。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM