我有一些代码可以在一堆Python Imaging Library(PIL)Image对象上执行(独立)操作。我想尝试使用并行处理加快速度,所以我读了下面的多处理模块:
http://docs.python.org/library/multiprocessing.html
但对于我来说,如何对这个问题使用多处理仍然不是很清楚。
从概念上讲,看起来我可以使用Image对象的多处理.Queue并使用工作池。但是Image对象似乎“无法折叠”:
UnpickleableError: Cannot pickle <type 'ImagingCore'> objects
是否有更好的方法可以并行处理PIL图像?
答案 0 :(得分:2)
如果从文件中获取图像对象,则只需将文件名发送给工作人员,让他们自己打开图像。
否则,您可以发送图像数据(包含Image.getdata()
)以及尺寸和像素格式,让工作人员使用Image.new()
和Image.putdata()
重建图像。
答案 1 :(得分:2)
只需将文件名放在列表中,然后让工作进程处理它们。以下示例使用ImageMagick中的subprocess从隐藏格式进行一些图像转换。但是PIL可以使用相同的原理。只需替换processfile()
函数的内容即可。这是我经常用来将DICOM文件(医学成像中使用的格式,在这种情况下从X光机)转换为PNG格式的程序。
"""Convert DICOM files to PNG format, remove blank areas. The blank erea
removal is based on the image size of a Philips flat detector. The image
goes from 2048x2048 pixels to 1574x2048 pixels."""
import os
import sys
import subprocess
from multiprocessing import Pool, Lock
globallock = Lock()
def checkfor(args):
"""Make sure that a program necessary for using this script is
available.
Arguments:
args -- string or list of strings containing a command to test
"""
if isinstance(args, str):
args = args.split()
try:
f = open('/dev/null')
subprocess.call(args, stderr=subprocess.STDOUT, stdout=f)
f.close()
except:
print "Required program '{}' not found! exiting.".format(args[0])
sys.exit(1)
def processfile(fname):
"""Use the convert(1) program from the ImageMagick suite to convert the
image and crop it.
Arguments:
fname -- string containing the name of the file to process
"""
size = '1574x2048'
args = ['convert', fname, '-units', 'PixelsPerInch', '-density', '300',
'-crop', size+'+232+0', '-page', size+'+0+0', fname+'.png']
rv = subprocess.call(args)
globallock.acquire()
if rv != 0:
print "Error '{}' when processing file '{}'.".format(rv, fname)
else:
print "File '{}' processed.".format(fname)
globallock.release()
def main(argv):
"""Main program.
Arguments:
argv -- command line arguments
"""
if len(argv) == 1:
# If no filenames are given, print a usage message.
path, binary = os.path.split(argv[0])
print "Usage: {} [file ...]".format(binary)
sys.exit(0)
# Verify that the convert program that we need is available.
checkfor('convert')
# Apply the processfile() function to all files in parallel.
p = Pool()
p.map(processfile, argv[1:])
p.close()
if __name__ == '__main__':
main(sys.argv)
答案 2 :(得分:0)
另一个选择是将convert PIL图像变成numpy数组,这些数组是可选择的。
from __future__ import print_function
import numpy
import pickle
my_array = numpy.array([1,2,3])
pickled_array = pickle.dumps(my_array)
print('The pickled version of %s is:\n\n%s.' % (my_array, pickled_array))