使用python进行多处理以查找Max值

时间:2014-05-07 01:16:21

标签: python multithreading python-2.7 opencv multiprocessing

我正在使用Python 2.7.5和OpenCV。我有一个测试图像,我想在图像阵列中找到它最相似的图像。我已经使用OpenCV编写了一个函数,它将给出相似点的总数。我拥有的点越相似,图像就越相似。不幸的是,这是一个相当耗时的功能,所以我想并行化我的代码以使其更快。

#img is the image that I am trying to find the most number of similar pointswith
maxSimilarPts = 0;

#testImages is a list of testImages
for testImage in testImages:
    #getNumSimilarPts returns the number of similar points between two images
    similarPts = getNumSimilarPts(img, testImage) 

    if similarPts > maxSimilarPts:
        maxSimilarPts = similarPts

我如何与python并行执行此操作?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

以下是原始代码的(未经测试的)并行版本。它并行运行5名工人。每个人从输入队列中获取一个图像,计算相似之处,然后将值和图像放到输出队列中。完成所有工作后,没有更多图像,然后父进程打印出最相似图像的(相似性,imageID)。

# adapted from Raymond Hettinger
# http://stackoverflow.com/questions/11920490/how-do-i-run-os-walk-in-parallel-in-python/23779787#23779787

from multiprocessing.pool import Pool
from multiprocessing import JoinableQueue as Queue
import os, sys


def parallel_worker():
    while True:
        testImage = imageq.get()
        similarPts = getNumSimilarPts(img, testImage) 
        similarq.put( [similarPts, testImage] )
        imageq.task_done()

similarq = Queue()
imageq = Queue()
for testImage in testImages:
    imageq.put(testImage)

pool = Pool(5)
for i in range(5):
    pool.apply_async(parallel_worker)

imageq.join()
print 'Done'

print max(similarq)

答案 1 :(得分:0)

重要提示:

此代码仅可在python3上本地运行。要在python2上运行它,您必须安装concurrent.futures PyPI package

from concurrent.futures import ProcessPoolExecutor


def multiprocess_max(iterable, key):
    with ProcessPoolExecutor() as executor:
        return max(executor.map(lambda item: (item, key(item)), iterable),
                   key=lambda item: item[1])[0]

背后的想法是:

昂贵的过程正在计算用于比较商品的钥匙。 因此,什么不通过多进程计算密钥而是仅使用一个进程进行比较呢?

这是它的工作方式:

创建一个concurrent.futures.ProcessPoolExecutor,它是multiprocessing模块周围的一个易于使用的包装,并提供一个map()函数,类似于内置函数,但可以同时工作。

然后,从集合中为每个项目创建具有2个元素的元组:原始项目(如果键为最大,我们要返回的值)和由传递的key函数计算的键。

得到结果后,将其传递给内置的max()-但是我们有一个问题:现在的集合是元组的集合!因此,我们传递了一个key函数,该函数返回第二项-计算键。

最后,由于max()返回了整个项目(包括不需要的密钥),因此我们从结果中提取第一个项目(原始项目)并返回。

编辑:

在此代码锁定在我的控制台中之后(IDLE;我发现这个问题是因为我也需要它),我认为我的解决方案是错误的:-)

但是我错了,不是解决方案。 此解决方案在解释器中不起作用。来自the docs

  

__main__模块必须可由工作程序子进程导入。这个   表示ProcessPoolExecutor在互动广告中无效   解释器。