【问题标题】:opencv: show an image and wait for variable to change, instead of waiting for a keypressopencv:显示图像并等待变量更改,而不是等待按键
【发布时间】:2019-01-30 18:15:42
【问题描述】:

我有一个生成系统,可以永远持续生成图像 - 它可能每隔一两秒生成一个新图像,但并不一致。

我想显示从系统输出的每个新图像,并且我想显示该图像,直到系统输出另一个图像,然后我将显示该图像。结果看起来像是生成的图像的连续流。

问题是 cv2 要求我输入“waitKey” - 这将等待数毫秒或直到按下某个键。如果我不包含“waitKey” - 图片一显示就会立即消失。

有什么方法可以让 cv2 在变量更新之前显示图像?

现在我的代码如下:

while True:
        finalimage = generate_image() # this part takes a second, give or take.
        cv2.imshow("window", finalimage)
        cv2.waitKey(2000)

但这需要我为每张图像等待 2 秒……这可以加快速度。另外 - 如果生成图像需要超过 2 秒的时间,脚本会搞砸。

TLDR:有什么方法可以无限期地显示带有 cv2 的图像,直到变量被更新/更改 - 而无需暂停程序以等待键输入?

【问题讨论】:

  • 您可以在单独的线程中更新finalimage,并让OpenCV imshow/waitkey 在主线程中运行,这样可以使您的界面保持响应并尽快显示图像。您可以放置​​一个 100 毫秒的等待键,以便在准备好时显示您的新图像

标签: opencv infinite-loop sleep keypress cv2


【解决方案1】:

通常的方法是将GUI部分与生成图像的部分分开。为此,只需将生成放在另一个线程中。这是一个小示例代码,说明如何做到这一点。

import numpy as np
import cv2
from threading import Thread, Lock
import time # not really needed, used to simulate the 2 seconds of generation

lock = Lock()

class ImageGenerator:
    def __init__(self, src=0):
      # initialize it with zeros to always have something to show. You can set it to None and check it outside before displaying
      self.frame = np.zeros((100,100,1))
      self.stopped = True

    def start(self):
     # checks if the generator is still running, to avoid two threads doing the same
     if not self.stopped:
       return
     self.stopped = False
     #Launches a thread to update itself
     Thread(target=self.update, args=()).start()
     return self

    def update(self):
      # go until stop is called, you can set other criterias
      while True:
        if self.stopped:
          return
        # generate the image, this is equal to finalimage = generate_image() in your code
        image = np.random.randint(0,255, (600, 800, 3), dtype=np.uint8)
        # this sleep is to simulate that it took longer to execute
        time.sleep(2)
        with lock:
          self.frame = image

    # if this changes the other thread will stop
    def stop(self):
      self.stopped = True

    # gets latest frame available  
    def get(self):
      return self.frame

# creates the object and start generating
imGen = ImageGenerator()
imGen.start()
# infinite loop to display the image, it can be stopped at any point with 'q'
while (True):
    cv2.imshow("Image", imGen.get())
    k = cv2.waitKey(50) & 0xFF
    if k == ord('q'):
      break;
# stops the generator and the other thread
imGen.stop()    
cv2.destroyAllWindows()

这样可以更新图像,OpenCV 会尽快显示它,并且仍然有一些响应式 GUI,您可以在其中执行其他操作(如键绑定)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 2019-01-02
    • 2021-02-27
    • 2020-04-13
    相关资源
    最近更新 更多