2015-03-17 9 views
6

Sto lavorando su Ubuntu 14.04 con Python 3.4 (Numpy 1.9.2 e PIL.Image 1.1.7). Ecco cosa faccio:Perché Python si blocca quando provo a sommare questo array numpy?

>>> 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) 

A me sembra come se Python esaurisse la memoria all'improvviso. In questo caso, come posso allocare più memoria in Python? Come posso vedere da htop la mia capacità di memoria da 32 GB non è neanche lontanamente depleated.

È possibile scaricare l'immagine TIFF here.


Se creo un array booleano vuoto, impostare i pixel esplicitamente e quindi applicare la sommatoria - allora funziona:

>>> 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) 

Ma questa "soluzione" non è molto soddisfacente come la copia di ogni pixel prende troppo lungo - forse c'è un metodo più veloce?

+2

un errore di segmentazione * sempre * indica un bug. Anche se Python fosse a corto di memoria, sarebbe un bug per farlo andare in crash con un errore di segmentazione invece di lanciare un errore di memoria insufficiente. –

+1

È concepibile che si stia esaurendo lo spazio disponibile. Il fatto che non lo si faccia nel caso casuale 10000 x 10000 potrebbe indicare una differenza nell'algoritmo utilizzato per le sezioni dell'array rispetto a quello utilizzato per interi array. Se per le sezioni si utilizzava un algoritmo ricorsivo, una sezione di array con molti segmenti discontinui potrebbe recidiva troppo profondamente e esaurire la pila. Questo è tutto speculativo, ovviamente. –

+0

Anche il primo caso si arresta in modo anomalo quando non è in sezione e il secondo caso non si arresta in modo anomalo anche se in sezione. – Raffael

risposta

3

Posso riprodurre il tuo segfault usando numpy v1.8.2/PIL v1.1.7 installato dai repository di Ubuntu.

  • Se installo NumPy 1.8.2 in un virtualenv utilizzando pip (ancora utilizzando v1.7.1 PIL dai repository di Ubuntu), allora non vedo più il segfault.

  • Se faccio il contrario (installando PIL v1.1.7 usando pip, e usando numpy v1.8.2 dai repository di Ubuntu), ho ancora il segfault.

Questo mi porta a credere che sia causato da un vecchio bug in numpy. Non sono stato in grado di trovare un buon candidato nel tracker dei problemi di numpy, ma sospetto che l'aggiornamento di numpy (ad esempio dalla sorgente corrente o tramite pip) probabilmente risolverebbe il problema.

Una soluzione è quella di convertire la modalità foto alla "P" (unsigned int 8-bit) prima di creare l'array, quindi la conversione di nuovo a booleano:

arr2 = np.asarray(img.convert("P")).astype(np.bool) 
v = arr2[1:800,1:100].sum(axis=0) 
+0

confermato - grazie – Raffael

Problemi correlati