【发布时间】: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