Python 为什么OpenCV和Matplotlib在更新显示时强制延迟?

Python 为什么OpenCV和Matplotlib在更新显示时强制延迟?,python,opencv,matplotlib,real-time,Python,Opencv,Matplotlib,Real Time,为什么OpenCV和Matplotlib都需要调用阻塞函数来更新显示 要在Matplotlib中显示图像(例如“i”),通常需要执行以下操作: import matplotlib.pyplot as plt plt.imshow(i, cmap="gray") plt.pause(0.001) 在OpenCV中,您通常会执行以下操作: import cv2 as cv cv.imshow("image", i) cv.waitKey(1) 在每种情况下

为什么OpenCV和Matplotlib都需要调用阻塞函数来更新显示

要在Matplotlib中显示图像(例如“i”),通常需要执行以下操作:

import matplotlib.pyplot as plt
plt.imshow(i, cmap="gray")
plt.pause(0.001)
在OpenCV中,您通常会执行以下操作:

import cv2 as cv
cv.imshow("image", i)
cv.waitKey(1)
在每种情况下,最后一行调用一个函数,该函数更新内部、处理事件和块一毫秒(在我的示例中,我认为1毫秒是可以传递的最小值)

来自实时嵌入式系统的背景,强制执行最小1毫秒的数据块(任何数量)似乎都是荒谬的。为什么这样做

我完全理解:

  • 事件需要维护,内部需要更新(因此您必须调用一些东西)
  • 在大多数/许多情况下,至少需要1毫秒
  • 1毫秒是一个足够短的时间,它几乎没有实际影响
然而,从实时角度来看,任何不必要的块(甚至一毫秒)通常都是需要避免的。如果没有必要,为什么要将程序减慢1毫秒?这会浪费线程用于其他用途的时间。为什么没有一个调用来执行所有必要的更新/事件服务,然后立即返回,而不是阻塞

(实际上,OpenCV的C++接口有<代码> CV::PrEpKy()/<代码>,但它不输出到Python) 我想做OpenCV和Matplotlib的人对此有很好的理由(我的意思是,两个独立的小组做了同样的事情)。我认为他们知道自己在做什么——我尽量不傲慢,认为他们错了,但不知道这样做的原因是什么


这种看似荒谬的设计背后的基本原理是什么?

这不是我通常显示图像的方式。我通常会:

import matplotlib.pyplot as plt
plt.imshow(i)
plt.show()
但要回答你的问题,在等待事件发生时,别无选择。选项包括:(1)在接收到事件之前关闭控制,(2)在特定时间段内关闭控制,(3)从不关闭控制


除了说“你想让我等多久”之外,你还会怎么做呢?我觉得这很自然。如果您的代码当前无法腾出1毫秒,那么请不要腾出1毫秒,并在可以的时候调用更新循环。

OpenCV的HighGUI模块是一个方便的工具,足以用于快速原型。使用matplotlib后,速度绝对不是它的优势。我想说,没有人能想象它们中的任何一个在实时循环中。@DanMašek你是对的,Matplotlib显示图像的速度慢得令人绝望,但它对于显示实时变化的图形非常方便,所以问题仍然存在——为什么会这样?我想做这件事的人有很好的理由,但他们不知道那是什么。重新打开cv,是否有比使用cv.imshow()更快的方法?什么?您使用适合您的需要/要求的框架编写自己的UI代码。根据我的经验,大多数UI应用程序将大部分时间花在消息循环中,特别是如果您希望UI响应速度快,那么实际上不需要以亚毫秒的间隔更新屏幕。任何严重的数字运算都会转移到其他线程。这是正确的。有更多的细节。如果你想刷新mpl中的事件循环,你可以执行
fig.canvas.flush\u events
,这将清除呼叫时挂起的UI事件(但不会在服务这些事件时添加任何事件)。我完全被你的回答弄糊涂了,对不起。对事件进行轮询有什么问题?不用等了。只需询问“是否有未决事件?”如果是,请为其提供服务。如果没有,就去做些别的事情——稍后再检查。为什么需要等待??不知何故,我的世界模型似乎与你以及Matplotlib和OpenCV的作者截然不同。为什么不必要的等待(浪费线程周期,甚至是一些几乎不会错过的线程周期)是个好主意?很明显,你“明白了”,而我不明白-你能解释给我听吗?当然,我很乐意。事实上,我发现你以这种方式看待这件事很有趣,我正试图理解你的观点。无论如何,一定有什么东西在为这些活动服务。当你启动一个程序时,你会得到一个线程和一个进程。当您编写的代码调用库函数(例如plt.imshow())时,该库代码仍然在您的进程和线程的上下文中运行——这些都是在您最初执行程序时由操作系统创建的。所以你似乎在问,“为什么matplotlib和OpenCV不需要一个过程呢?”(?)@mmiron谢谢你的尝试;不知何故,我们没有很好地沟通。我完全理解这些库需要一个过程,事件需要服务。因此,需要定期调用一些函数来进行维护。我不明白的是,为什么需要与该服务功能相关联的空闲延迟(1ms或其他)。为什么函数不能只做它的服务,然后立即返回?为什么要增加延迟(即使很小)?我真的不明白!正如您在上面的
imshow()
的docstring中所看到的,它确实为您提供了一个根本不等待的选项:调用
plt.imshow(block=False)
,它将完全按照您认为的“最佳”方式执行。如果您想查看程序在不为事件提供服务时的外观,请在终端启动GUI程序,然后在Linux中按CTRL+Z。然后单击/移动窗口。这就是程序在不“等待”事件时的样子。不是很好的用户体验:事件驱动的代码大部分时间都在等待事件/触发器。有道理?
>>> help(plt.show)
show(*, block=None)
    Display all open figures.
    
    In non-interactive mode, *block* defaults to True.  All figures
    will display and show will not return until all windows are closed.
    If there are no figures, return immediately.
    
    In interactive mode *block* defaults to False.  This will ensure
    that all of the figures are shown and this function immediately returns.
    
    Parameters
    ----------
    block : bool, optional
    
        If `True` block and run the GUI main loop until all windows
        are closed.
    
        If `False` ensure that all windows are displayed and return
        immediately.  In this case, you are responsible for ensuring
        that the event loop is running to have responsive figures.
    
    See Also
    --------
    ion : enable interactive mode
    ioff : disable interactive mode