【问题标题】:Python mss only capturing 60 fps, even with multiprocessing?即使使用多处理,Python mss 也只能捕获 60 fps?
【发布时间】:2022-10-15 05:50:40
【问题描述】:

我使用mss 进行屏幕捕捉已经有一段时间了,无论如何我都无法将其速度提高到60 fps 以上,即使使用multiprocessing 也是如此。这是代码:

import multiprocessing as mp
import time
import mss


def task():
    start = time.time()
    
    for x in range(600):
        with mss.mss() as sct:
            sct.grab({'mon': 1, 'top': 690, 'left': 750, 'width': 450, 'height': 50})

    print(time.time() - start)

if __name__ == '__main__':
    for x in range(3):
        p = mp.Process(target=task)
        p.start()

更改range() 函数中的int 不会对整体捕获速度产生影响。结果如下:

1 个进程,每个进程 60 fps,组合 60 fps,每个进程约 10 秒
2 个进程,每个进程 30 fps,组合 60 fps,每个进程约 20 秒
3 个进程,每个进程 20 fps,组合 60 fps,每个进程约 30 秒

有谁知道这可能是什么原因造成的?

需要注意的是,改变边界框({'mon': 1, 'top': 690, 'left': 750, 'width': 450, 'height': 50})的分辨率不会影响帧率。捕获我的整个屏幕,小到一个像素,一切都是 60 fps。

额外信息:
Python 3.10.4
Windows 10 笔记本电脑,华硕 TUF Gaming FXGT505-FXGT505
英特尔 I7 9750H、GTX 1650、16gb 内存、144hz 屏幕和 60hz 显示器作为主要
在我主动使用 mss 截屏进行图像处理的情况下,处理不会影响帧率,即使使用multiprocessing

【问题讨论】:

  • 我确信with mss.mss() as sct:sct.grab() 行在mss 库中获取了一些全局互斥锁。并且这个互斥体每秒只允许获取 60 次。我确信 MSS 库有一些 Grabber 的内部状态,这种状态每秒只产生 60 次屏幕,而不是更多。这应该是库本身的特殊限制。这可能是一种可调整的行为,在库中可能是将限制从 60 提高到 120 的配置。
  • @Arty 我很感激,但我想如果是这样的话,会有更多人遇到这个问题吗?在过去的几周里,我做了一些研究,试图看看是否有其他人遇到这个问题,但我找不到任何通过更改屏幕分辨率无法解决的问题。不过,假设你是对的,我将如何去寻找如何改变这一点?
  • @Arty 如果有什么不同,我通常在一行上做sct = mss.mss(),在另一行上做sct.grab(),它仍然提供同样的问题。
  • 这意味着锁定是在sct.grab() 内部获取的,而不是with 语句。我查看了该库的代码,它显示 sct.grab() 使用 Windows API 函数,如 CreateCompatibleBitmap()SelectObject()DeleteObject()BitBlt()GetDIBits()。我确信其中一个 Windows API 函数会插入一些暂停,例如 1/60 秒。此外,这些功能可能只是等到下一个监视器同步时间点,每 1/60 秒一次。所以这个暂停自然是由 Win API 插入的。
  • @Arty 你能指出我在哪个文件中找到了这些文件吗?它是site-packages/mss 目录中的文件,还是其他地方的文件?

标签: python python-3.x python-mss


【解决方案1】:

Arty 指出以下几点:

这意味着锁是在 sct.grab() 内部获取的,而不是使用语句。我查看了该库的代码,它显示 sct.grab() 使用 Windows API 函数,如 CreateCompatibleBitmap() 和 SelectObject() 和 DeleteObject() 以及 BitBlt() 和 GetDIBits()。我确信其中一个 Windows API 函数会插入一些暂停,例如 1/60 秒。此外,这些功能可能只是等到下一个监视器同步时间点,每 1/60 秒一次。所以这个暂停自然是由 Win API 插入的

结果,我完全断开了我的显示器,这确实将捕获速率提高到了 144 赫兹。断开我的显示器对我来说是一个很好的临时解决方案,但有些人只有 60hz 显示器,没有别的。一旦我弄清楚如何做到这一点,我将通过 Win Api 来寻找更永久的方法。任何帮助,将不胜感激。

需要注意的是,将正在捕获的监视器更改为 144hz 监视器仍会将捕获速率限制为 60fps。

【讨论】:

    猜你喜欢
    • 2020-07-12
    • 2018-10-28
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多