【问题标题】:Using multi-threading to process an image faster on python?在 python 上使用多线程更快地处理图像?
【发布时间】:2012-01-10 11:59:22
【问题描述】:

在 Python + Python 图像库脚本中,有一个名为 processPixel(image,pos) 的函数,它计算图像函数的数学索引及其上的位置。使用简单的 for 循环为每个像素计算此索引:

for x in range(image.size[0)):
    for y in range(image.size[1)):
        myIndex[x,y] = processPixel(image,[x,y])

这花费了太多时间。如何实现线程化以加快工作速度?多线程代码能有多快?具体来说,这是由处理器内核数定义的吗?

【问题讨论】:

  • 另外,我非常愿意打赌processPixel 可能是“numpy-ified”,在这种情况下,您会看到与当前方法相比有巨大的加速。

标签: python image-processing numpy gpu python-imaging-library


【解决方案1】:

由于Global Interpreter Lock,您无法使用线程加速它。 Python 解释器的某些内部状态受到该锁的保护,从而防止需要修改该状态的不同线程同时运行。

可以通过使用multiprocessing 生成实际进程来加速它。每个进程将在自己的解释器中运行,从而绕过线程的限制。通过多处理,您可以使用共享内存,也可以为每个进程提供自己的数据副本/分区。

根据您的任务,您可以通过分区来并行处理单个图像,也可以并行处理图像列表(后者可以使用pool 轻松完成)。如果您想使用前者,您可能希望将图像存储在可以作为共享内存访问的Array 中,但是您仍然必须解决将结果写入哪里的问题(写入共享内存可以严重损害性能)。另请注意,进程之间的某些类型的通信(队列、管道或模块中某些函数的参数/返回值传递)需要使用Pickle 序列化数据。这对数据施加了某些限制,并且可能会产生显着的性能开销(尤其是在您有许多小任务的情况下)。

提高此类操作性能的另一种方法是尝试在 Cython 中编写它们,它使用 OpenMP 有自己的 support for parallelization - 不过我从未使用过,所以我不知道它有多大帮助.

【讨论】:

  • 如果您正在处理图像(或者您正在执行任何需要大量计算能力的操作),那么您还应该查看 GPU。 Python 肯定支持它。
  • 正如@freakish 建议的那样,您应该使用GPU-based 解决此类问题。你所说的 GIL 和多处理是正确的,但对图像处理仍然没有帮助。在数组处理方面,我recommend using NumPy,因为它是为高效数组处理而设计的。
【解决方案2】:

以下是您想要探索以进行高效图像处理的库列表:

OpenCV - 是一个用于实时计算机视觉和图像处理的编程函数库,包含 Python 绑定。

PyOpenCL 可让您从 Python 访问 GPU 和其他大规模并行计算设备。

PyCUDAPyOpenCL 的姊妹项目

NumPy and SciPy 是进行科学计算的基础包,可能有助于上述包进行高效的图像和数组处理。

还要注意,对于图像处理,一些人建议的多处理库不会帮助您有效地处理图像处理,因此您应该避免使用操作系统线程来执行此操作。如果出于某种原因您确实需要粗粒度并行性,那么您可以使用python library for MPI,但您可能希望坚持使用GPU-based libraries

【讨论】:

    【解决方案3】:

    看看Doug Hellmans tutorial 的多处理。正如 Björn 指出的那样,您需要掌握有关并行处理的各种问题,但确实值得付出努力。

    提示:您可以使用multiprocessing.cpu_count() 来检查您可用的内核数量。

    【讨论】:

    • 教程上的linkrot
    猜你喜欢
    • 2015-06-17
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2017-01-27
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多