我的程序使用以下代码生成一系列窗口:</ 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窗户?感谢。
答案 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)
可以正常工作