【问题标题】:Parallelize Image Processing Using Numpy使用 Numpy 并行化图像处理
【发布时间】:2015-06-18 03:36:21
【问题描述】:

我正在尝试使用 python 中的并行处理来加速我的一段代码,但我无法让它正常工作,甚至无法找到与我相关的示例。

代码使用 Delaunay 三角剖分生成图像的低多边形版本,而让我慢下来的部分是找到每个三角形的平均值。

通过矢量化我的代码,我已经能够很好地提高速度,但希望通过并行化获得更多:

我遇到问题的代码是一个非常简单的 for 循环:

for tri in tris:
        lopo[tridex==tri,:] = np.mean(hipo[tridex==tri,:],axis=0)

引用的变量如下。

tris - 三角形所有索引的唯一 Python 列表

lopo - 图像的最终低多边形版本的 Numpy 数组

hipo - 原始图像的 Numpy 数组

tridex - 一个与图像大小相同的 Numpy 数组。每个元素代表一个像素并存储该像素所在的三角形

我似乎找不到一个使用多个 numpy 数组作为输入的好例子,其中一个是共享的。

我尝试过多重处理(上面的 sn-p 包含在一个名为 colorImage 的函数中):

p = Process(target=colorImage, args=(hipo,lopo,tridex,ppTris))
p.start()
p.join()

但是我立即得到一个损坏的管道错误。

【问题讨论】:

    标签: python numpy parallel-processing


    【解决方案1】:

    因此,Python 的多处理工作方式(大部分情况下)是您必须指定要运行的各个线程。我在这里做了一个简短的入门教程:http://will-farmer.com/parallel-python.html

    在您的情况下,我建议将 tris 拆分为一堆不同的部分,每个部分大小相同,每个部分代表一个“工人”。您可以使用numpy.split() 拆分此列表(此处的文档:http://docs.scipy.org/doc/numpy/reference/generated/numpy.split.html)。

    然后对于 tri 中的每个列表,我们使用 Threading 和 Queue 模块来指定 8 个 worker。

    import numpy as np
    # split into 8 different lists
    tri_lists = np.split(tris, 8)
    # Queues are threadsafe
    return_values = queue.Queue()
    threads = []
    def color_image(q, tris, hipo, tridex):
        """ This is the function we're parallelizing """
        for tri in tris:
            return_values.put(np.mean(hipo[tridex==tri,:], axis=0))
    # Now we run the jobs
    for i in range(8):
        threads.append(threading.Thread(
            target=color_image,
            args=(return_values, tri_lists[i], hipo, tridex)))
    # Now we have to cleanup our results
    # First get items from queue
    results = [item for item in return_values.queue]
    # Now set values in lopo
    for i in range(len(results)):
        for t in tri_lists[i]:
            lopo[tridex==t, :] = results[i]
    

    这不是最干净的方法,而且我不确定它是否有效,因为我无法对其进行测试,但这是一种不错的方法。并行化部分现在为np.mean(),而设置值未并行化。

    如果您还想并行设置值,则必须有一个共享变量,可以使用队列,也可以使用全局变量。

    有关共享全局变量,请参阅此帖子:Python Global Variable with thread

    【讨论】:

    • 线程不允许设置新值吗?我还没有完全检查,但我相信线程不会尝试写入相同的像素。同时进行平均计算和写作应该会给我希望看到的大幅加速。
    • 这也可以,但我从未在线程上使用共享变量。只要你只是设置像素,你应该没问题。是的,这也会给你一个更大的加速。请参阅我提供的 SO 链接作为示例。
    • 我似乎无法并行运行简单的函数。您是否知道即使使用并行化模块,脚本(在 IDLE 中运行)也会串行运行的任何原因?我的电脑上可能有一些设置限制了 IDLE 可以使用的线程数?
    • 我不知道,也许尝试从我的网页运行我的命令?看看这些有用吗?我不使用 IDLE,但我不会想象会有线程限制。先尝试做一些基本的测试,确保没有限制。如果您仍然遇到问题,请发布您的代码(甚至可以在原始帖子的编辑中),我会看看是否可以提供帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-10-21
    • 2016-11-05
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多