注意:我使用Python 2.x,将其移植到3.x并不难。
我的想法很简单-磁盘空间足够,所以让我们进行一些预处理,然后将大的pickle文件转换为更容易在小块中处理的文件。
制备
为了对此进行测试,我编写了一个小脚本,生成一个类似于您的泡菜文件。我假设您输入的图像是灰度图像,深度为8位,并使用生成了10000个随机图像
numpy.random.randint。
该脚本将作为基准,我们可以将其与预处理和处理阶段进行比较。
import numpy as npimport pickleimport timeIMAGE_WIDTH = 600IMAGE_HEIGHT = 600FILE_COUNT = 10000t1 = time.time()with open('data/raw_data.pickle', 'wb') as f: for i in range(FILE_COUNT): data = np.random.randint(256, size=IMAGE_WIDTH*IMAGE_HEIGHT, dtype=np.uint8) data = data.reshape(IMAGE_HEIGHT, IMAGE_WIDTH) pickle.dump(data, f) print i,t2 = time.time()print 'nDone in %0.3f seconds' % (t2 - t1)在测试运行中,此脚本在372秒内完成,生成了约10 GB的文件。
预处理
让我们逐行拆分输入图像-
我们将有600个文件,其中文件
N包含
N每个输入图像的行。我们可以使用来将行数据存储为二进制
numpy.ndarray.tofile(然后使用来加载这些文件
numpy.fromfile)。
import numpy as npimport pickleimport time# Increase open file limit# See https://stackoverflow.com/questions/6774724/why-python-has-limit-for-count-of-file-handlesimport win32filewin32file._setmaxstdio(1024)IMAGE_WIDTH = 600IMAGE_HEIGHT = 600FILE_COUNT = 10000t1 = time.time()outfiles = []for i in range(IMAGE_HEIGHT): outfilename = 'data/row_%03d.dat' % i outfiles.append(open(outfilename, 'wb'))with open('data/raw_data.pickle', 'rb') as f: for i in range(FILE_COUNT): data = pickle.load(f) for j in range(IMAGE_HEIGHT): data[j].tofile(outfiles[j]) print i,for i in range(IMAGE_HEIGHT): outfiles[i].close()t2 = time.time()print 'nDone in %0.3f seconds' % (t2 - t1)在测试运行中,此脚本在134秒内完成,生成了600个文件,每个文件600万字节。它使用了约30MB或RAM。
处理中
很简单,只需使用加载每个数组
numpy.fromfile,然后使用
numpy.median来获取每个列的中值,将其缩减为单行,并将这些行累加到列表中。
最后,用于
numpy.vstack重新组装中间图像。
import numpy as npimport timeIMAGE_WIDTH = 600IMAGE_HEIGHT = 600t1 = time.time()result_rows = []for i in range(IMAGE_HEIGHT): outfilename = 'data/row_%03d.dat' % i data = np.fromfile(outfilename, dtype=np.uint8).reshape(-1, IMAGE_WIDTH) median_row = np.median(data, axis=0) result_rows.append(median_row) print i,result = np.vstack(result_rows)print resultt2 = time.time()print 'nDone in %0.3f seconds' % (t2 - t1)
在测试运行中,此脚本在74秒内完成。您甚至可以很容易地并行化它,但这似乎不值得。该脚本使用了约40MB的RAM。
给定这两个脚本的线性关系,所用时间也应线性变化。对于50000张图像,预处理大约需要11分钟,最终处理大约需要6分钟。这是在i7-4930K @3.4GHz上,故意使用32位Python。



