DestroyWindow не закрывает окно на Mac, используя Python и OpenCV - PullRequest
28 голосов
/ 25 мая 2011

Моя программа генерирует серию окон, используя следующий код:

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, запускаю программу в Терминале. Как я могу закрыть окна графического интерфейса? Спасибо.

Ответы [ 11 ]

27 голосов
/ 25 февраля 2013

Вам нужно запустить 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"

Та же проблема происходит с C ++версия для Linux: Попытка закрыть окно OpenCV не дает никакого эффекта

21 голосов
/ 10 июня 2011

Есть несколько особенностей графического интерфейса в OpenCV.Вызов destroyImage не может закрыть окно (по крайней мере, в Linux, где бэкэнд по умолчанию был Gtk + до 2.1.0), если только waitKey не был вызван для прокачки событий.Добавление вызова waitKey(1) сразу после destroyWindow может работать.

Даже в этом случае закрытие не гарантируется;функция waitKey перехватывается только в том случае, если окно имеет фокус, и поэтому, если окно не имело фокусировки во время вызова destroyWindow, скорее всего, оно останется видимым до следующего вызова destroyWindow.1010 *

Я предполагаю, что это поведение связано с Gtk +;эта функция не доставляла мне никаких проблем, когда я использовал ее под Windows.

16 голосов
/ 11 сентября 2014

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)

Сработало также.Я не достаточно сообразителен, чтобы знать, почему это работает точно, хотя я предполагаю, что это как-то связано с прерыванием и задержкой, созданными зацикливанием этого кода (?)

Маттеус Брандл сказал выше, что третий waitKey) работал на него, так что, возможно, он немного отличается в каждой системе?(Я использую Linux Mint с ядром 3.16.1 и python 2.7)

Задержка, сама по себе, не объясняет этого, поскольку простое увеличение времени задержки в waitKey () не помогает.(Также зацикливание print ("Hello") 1000 раз вместо использования wiatKey () просто для того, чтобы увидеть, помогла ли созданная задержка - нет.) Должно быть что-то большее, как waitKey () взаимодействует с событиями окна.

Документы OpenCV говорят: "Эта функция - единственный метод в HighGUI, который может извлекать и обрабатывать события, поэтому его необходимо периодически вызывать для обычной обработки событий, если только HighGUI не используется в среде, которая заботится ообработка события. "

Возможно, он создает своего рода прерывание на дисплее графического интерфейса, которое позволяет обрабатывать действие destroyAllWindows ()?

J

4 голосов
/ 03 октября 2012

Это решение работает для меня (под Ubuntu 12.04 с открытым python в оболочке):

Повторно вызвать cv.ShowImage после того, как окно «разрушено».

3 голосов
/ 14 августа 2014

Я решил проблему, вызвав cv2.waitKey(1) в цикле for, я не знаю, почему это сработало, но выполнил свою работу, поэтому я не стал беспокоиться дальше.

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

Вы можете объяснить.

2 голосов
/ 09 июня 2017

Вот что у меня сработало:

cv2.namedWindow("image")
cv2.imshow('image', img)
cv2.waitKey(0) # close window when a key press is detected
cv2.destroyWindow('image')
cv2.waitKey(1)
2 голосов
/ 16 августа 2016

Если вы используете Spyder (пакет Anaconda), это проблема.

Ни одно из решений не сработало для меня. Я обнаружил, что проблема не в функциях, а в действительности в Spyder. Попробуйте использовать texteditor plus, работающий на терминале, и вы будете в порядке, просто:

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()
1 голос
/ 26 июля 2013

После поиска в течение некоторого времени ни одно из предложенных решений не сработало для меня, поэтому, поскольку в этой функции есть ошибка, и у меня не было времени ее исправить, мне не пришлось использовать окно 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.

1 голос
/ 25 марта 2013

Возиться с этой проблемой в консоли Python Я наблюдал следующее поведение:

  • выдача cv2.imshow после cv2.destroyWindow иногда закрывает окно.Хотя старое окно снова появляется при следующем вызове highgui, например, cv2.namedWindow
  • третий вызов cv2.waitKey после cv2.destroyWindow закрывает окно каждый раз, когда я пытался,Кроме того, закрытое окно оставалось закрытым, даже при использовании cv2.namedWindow впоследствии

Надеюсь, это кому-нибудь поможет.

(я использовал Ubuntu 12.10 с python 2.7.3, но OpenCV 2.4.2 изрепо 13.04)

0 голосов
/ 19 декабря 2018

Это сработало для меня в 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), чтобы это работало

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...