DestroyWindow does not close window on Mac using Python and OpenCV

后端 未结 12 1012
野趣味
野趣味 2020-11-27 05:36

My program generates a series of windows using the following code:

def display(img, name, fun):
    global clicked

    cv.NamedWindow(name, 1)
    cv.ShowIm         


        
相关标签:
12条回答
  • 2020-11-27 05:38

    Here is what worked for me:

    cv2.namedWindow("image")
    cv2.imshow('image', img)
    cv2.waitKey(0) # close window when a key press is detected
    cv2.destroyWindow('image')
    cv2.waitKey(1)
    
    0 讨论(0)
  • 2020-11-27 05:40

    It seems that none of the above solutions worked for me if I run it on Jupyter Notebook (the window hangs when closing and you need to force quit Python to close the window).

    I am on macOS High Sierra 10.13.4, Python 3.6.5, OpenCV 3.4.1.

    The below code works if you run it as a .py file (source: https://www.learnopencv.com/read-write-and-display-a-video-using-opencv-cpp-python/). It opens the camera, records the video, closes the window successfully upon pressing 'q', and saves the video in .avi format.

    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() 
    
    0 讨论(0)
  • 2020-11-27 05:41

    You need to run cv.startWindowThread() after opening the window. I had the same issue and now this works for me.

    Hope this helps for future readers. And there is also a cv2 binding (I advise to use that instead of cv).

    This code works for me:

    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"
    

    The same issue happens with the C++ version, on Linux: Trying to close OpenCV window has no effect

    0 讨论(0)
  • 2020-11-27 05:42

    Sayem2603

    I tried your solution and it worked for me - thanks! I did some trial and error and discovered that looping 4 times did the trick for me... or posting the same code 4 times just the same..

    Further, I drilled down to:

    cv2.destroyAllWindows()
    cv2.waitKey(1)
    cv2.waitKey(1)
    cv2.waitKey(1)
    cv2.waitKey(1)
    

    or simply calling DestroyAllWindows and then looping the waitKey() code 4 times:

    cv2.destroyAllWindows()
    for i in range (1,5):
        cv2.waitKey(1)
    

    Worked as well. I am not savvy enough to know why this works exactly, though I assume it has something to do with the interruption and delay created by looping that code(?)

    Matthäus Brandl said, above, that the third waitKey() worked for him, so perhaps it is slightly different on each system? (I am running Linux Mint with 3.16.1 kernel and python 2.7)

    The delay, alone, doesn't explain it, as simply increasing the delay time on the waitKey() does not do the trick. (Also looped print("Hello") 1000 times instead of using wiatKey() just to see if the delay that created helped any - it did not.) Must have something more to do with how waitKey() interacts with window events.

    OpenCV Docs say: "This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing."

    Perhaps it creates an interrupt of sorts in the GUI display that allows the destroyAllWindows() action to process?

    J

    0 讨论(0)
  • 2020-11-27 05:43

    I solved the problem by calling cv2.waitKey(1) in a for loop, I don't know why it worked but gets my job done, so I didn't bother myself further.

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

    you are welcome to explain.

    0 讨论(0)
  • 2020-11-27 05:46

    I had the same issue. The problem is that while(cap.isOpened()): loop does not finish so that I added below structure. When video has no frame in the following part, it returns ret values as False. Normally, I put destroyAllWindows command out of loop but I moved it into the loop. It works in my code properly.

    while(cap.isOpened()):
     ret, frame = cap.read()  
     if ret == False:
            cap.release()
            cv2.waitKey(1)
            cv2.destroyAllWindows()
            cv2.waitKey(1)
    
    0 讨论(0)
提交回复
热议问题