我有一个图像列表(称为screens
(,我正在拍摄当前窗口的屏幕截图,然后将OpenCV中的屏幕截图与列表进行比较,以了解打开了哪个屏幕。我使用for循环来做这件事,但一次比较一个图像会使我的软件速度变慢。所以,我转向了多处理。下面是它的代码:
def cpu_bound(template):
for i in range(len(screens)):
#compare_images is function to find similarity
result= compare_images(screen[i],template)
if result is True:
return i
return -1
def find_screen(template):
with multiprocessing.Pool() as pool:
i=pool.map(cpu_bound, template)
return i
对于find_screen
,我正在传递屏幕截图,但在多处理中,我收到一个错误,即输入图像在这一行上的尺寸不相同:
result= compare_images(screens[i],template)
尽管没有多处理的循环运行良好。我在实现多处理时犯了什么错误?
您正试图将函数(cpu_bound
(映射到单个值(template
(上,而函数本身(在所有screens
上(执行循环。这行不通。
相反,直接使用compare_images
:
with multiprocessing.Pool() as pool:
result = pool.map(lambda screen: compare_images(screen, template), screens)
您应该一个接一个地进行池。下面是一个例子。
from multiprocessing import Pool
from functools import partial
def func(x, found):
if x == found:
return True
else:
return False
if __name__ == '__main__':
asd = [1, 2, 3]
to_be_found = 3
f = partial(func, to_be_found)
with Pool() as p:
print(p.map(f, asd))
你似乎得到了另一种方式。map
获取一个函数和一个可迭代函数,并在可迭代函数的每个元素上运行该函数。但是您将template
图像作为可迭代对象传递,因此会出现这个奇怪的错误。你可能想做:
i = pool.map(cpu_bound, screens)
这将需要您稍微更改cpu_bound
:
def cpu_bound(screen):
#compare_images is function to find similarity
result = compare_images(screen, template)
if result is True:
return screen
return -1
这是假设您使用的是全局变量。如果不是这样,您可以使用starmap
来传递多个参数。cpu_bound
将是:
def cpu_bound(screen, template):
...
你会称之为:
from itertools import repeat
...
i = pool.starmap(cpu_bound, zip(screens, repeat(template)))