python - 使用多重处理来存储大图像

标签 python multiprocessing

我在 PyQt5 中编写了一个应用程序/Gui,并且想要存储大图像(>5000 个 RGB 图像)

现在,我有一个函数,它用cv2.imwrite存储每张图片,但是这个过程需要很多时间。所以我在 Stackoverflow 上读到,我可以通过多处理来做到这一点。但我对 python 很陌生。

我的多处理代码:

def SaveImages(self):
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target = self.SaveAllImages, args=self)
        jobs.append(p)
        p.start()

在函数 SaveAllImages 中,是存储每帧图像的基本代码。如果我运行此代码 - 出现错误:

p = multiprocessing.Process(target = SaveAllImages, args=self)
NameError: name 'SaveAllImages' is not defined

但 SaveAllImages 已定义:def SaveAllImages(self)

所以我的问题是:

  1. 为什么我会出现这个错误

  2. 如何实现非常简单的多重处理来存储图像

最佳答案

您看到的错误是因为您调用了一个不存在的方法,可能是因为它不是 self 的一部分。

您可能会看到多线程比多处理更好的性能。多处理最适合 CPU 密集型任务,原因很简单,Python 对所有操作都使用全局锁。多处理是绕过这个锁的一种技巧。它比线程更麻烦,除非绝对必要,否则最好避免使用它。

线程可能足以满足您的用例,并且不会给新程序员带来很多麻烦。这是使用 Python 3 的 Futures API 的工作示例设置这将轻松扩展您的问题规模,只需在标记的位置添加您的参数和实际保存代码即可。

import concurrent.futures

# Save single image
def save_image(image_arg):
    # your image save code goes here
    print("Working on image {}...".format(image_arg))
    return True

# max_workers specifies the number of threads. If None then use 5x your CPU count
with concurrent.futures.ThreadPoolExecutor(max_workers=None) as executor:
    # Images we'll save. Depending on how you generate your images you might not
    # want to materialize a list like this to avoid running out of memory.
    image_args = ["image1", "image2", "image3"]

    # Submit futures to the executor pool.
    # Map each future back to the arguments used to create that future. That way
    # if one fails we know which image it was that failed.
    future_to_args = {executor.submit(save_image, image_arg): image_arg for image_arg in image_args}

    # Images are being saved in worker threads. They will complete in any order.
    for future in concurrent.futures.as_completed(future_to_args):
        image_arg = future_to_args[future]
        try:
            result = future.result()
        except Exception as exc:
            print("Saving image {} generated an exception: {}".format(image_arg, exc))
        else:
            print("Image {} saved successfully.".format(image_arg))

如果您坚持多处理,只需使用ProcessPoolExecutor即可。如果您还想并行生成图像,这可能是值得的。

ThreadPoolExecutor 还是 ProcessPoolExecutor 哪个更好,很大程度上取决于您的其余工作负载是什么以及您如何构建它。两者都尝试一下,看看哪种更适合您。请注意,多处理对工作人员之间的通信和共享状态施加了限制,因此我建议首先尝试线程。

关于python - 使用多重处理来存储大图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57632036/

相关文章:

python - Python 中 multiprocessing.manager 的替代方案

python - 最佳数量的进程可同时写入大量文件

Python 使用多处理

python - 确定 MIME 类型是二进制的还是基于文本的

python-2.7 - 使用 pyodbc 与多处理并行更新 MSSQL 表时出现太多死锁错误

python - 多处理模块和pyro的比较?

python - 识别在特定分位数 : data science pandas 中的观察

python - 如何在Python中对多个文件进行逐行排序?

python - 使用另一个数据帧的多索引过滤一个数据帧

python - 将 zipfile 提取代码从 ruby​​ 转换为 python