【发布时间】:2015-03-17 17:54:01
【问题描述】:
我正在使用 Python 3.4(Numpy 1.9.2 和 PIL.Image 1.1.7)在 Ubuntu 14.04 上工作。这是我的工作:
>>> from PIL import Image
>>> import numpy as np
>>> img = Image.open("./tifs/18015.pdf_001.tif")
>>> arr = np.asarray(img)
>>> np.shape(arr)
(5847, 4133)
>>> arr.dtype
dtype('bool')
# all of the following four cases where I incrementally increase
# the number of rows to 700 are done instantly
>>> v = arr[1:100,1:100].sum(axis=0)
>>> v = arr[1:500,1:100].sum(axis=0)
>>> v = arr[1:600,1:100].sum(axis=0)
>>> v = arr[1:700,1:100].sum(axis=0)
# but suddenly this line makes Python crash
>>> v = arr[1:800,1:100].sum(axis=0)
fish: Job 1, “python3” terminated by signal SIGSEGV (Address boundary error)
在我看来,Python 突然内存不足。如果是这种情况 - 我如何为 Python 分配更多内存?正如我从 htop 中看到的那样,我的 32GB 内存容量甚至没有被远程耗尽。
您可以下载 TIFF 图片here。
如果我创建一个空布尔数组,明确设置像素,然后应用求和 - 然后它就可以了:
>>> arr = np.empty((h,w), dtype=bool)
>>> arr.setflags(write=True)
>>> for r in range(h):
>>> for c in range(w):
>>> arr.itemset((r,c), img.getpixel((c,r)))
>>> v=arr.sum(axis=0)
>>> v.mean()
5726.8618436970719
>>> arr.shape
(5847, 4133)
但是这种“解决方法”并不是很令人满意,因为复制每个像素的时间太长了——也许有更快的方法?
【问题讨论】:
-
分段错误总是表示存在错误。即使 Python 内存不足,它也会因分段错误而崩溃而不是引发内存不足错误。
-
可以想象你的堆栈空间已经用完了。在 10000 x 10000 随机情况下不这样做可能表明用于数组部分的算法与用于整个数组的算法存在差异。如果对部分使用递归算法,则具有许多不连续段的数组部分可能会递归得太深并耗尽堆栈。当然,这都是推测性的。
-
第一种情况在不切片时也会崩溃,第二种情况在切片时也不会崩溃。
-
我最好的猜测是,
numpy.asarray()正在生成一个由部分或全部 Image 对象支持的数组(而不是将所有像素值复制到单独的内部表示),并且 numpy和 PIL 不同意图像的预期行为的某些方面(或者 PIL 可能只是错误)。您可以通过从 Image 对象中手动提取像素栅格并围绕它构建您的 numpy 数组来探测和/或解决该问题。 -
您能告诉我们您使用的是哪个版本的 PIL 和 numpy 吗?
标签: python python-3.x numpy