2014-12-16 9 views
6

Sto facendo qualche lavoro per cui devo caricare un manipolare immagini CT in un formato chiamato Analyze 7.5 file format.Caricamento immagini di formato 7.5 in python

Parte di questa manipolazione, che richiede anni senza problemi con immagini di grandi dimensioni, consiste nel caricare i dati binari non elaborati in una matrice numpy e ridisegnarla alle dimensioni corrette. Ecco un esempio:

headshape = (512,512,245) # The shape the image should be 
headdata = np.fromfile("Analyze_CT_Head.img", dtype=np.int16) # loads the image as a flat array, 64225280 long. For testing, a large array of random numbers would do 

head_shaped = np.zeros(shape=headshape) # Array to hold the reshaped data 

# This set of loops is the problem 
for ux in range(0, headshape[0]): 
    for uy in range(0, headshape[1]): 
     for uz in range(0, headshape[2]): 
      head_shaped[ux][uy][uz] = headdata[ux + headshape[0]*uy + (headshape[0]*headshape[1])*uz] # Note the weird indexing of the flat array - this is the pixel ordering I have to work with 

So NumPy può fare rimodulazione degli array in fretta, ma io non riesco a capire la giusta combinazione di trasformazioni necessarie per replicare l'effetto dei cicli annidati.

C'è un modo per replicare quella indicizzazione strana con una combinazione di numpy.reshape/numpy.ravel ecc.?

risposta

0

Si potrebbe utilizzare rimodellare in combinazione con swapaxes

headshape = (2,3,4) 
headdata = rand(2*3*4) 

head_shaped_short = headdata.reshape(headshape[::-1]).swapaxes(0,2) 

ha funzionato bene nel mio caso.

+0

Esattamente il codice che stavo cercando, grazie! – Theolodus

0

numpy memorizza gli array nella memoria. L'attributo strides contiene le informazioni necessarie su come mappare gli indici multidimensionali agli indici piatti nella memoria.

Here è un'ulteriore lettura sul layout di memoria di numpy.

Questo dovrebbe funzionare per voi:

# get the number of bytes of the specified dtype 
dtype = headdata.dtype 
byte_count = dtype.itemsize 

headdata = headdata.reshape(headshape) 
x, y, z = headshape 
headdata.strides = (byte_count, byte_count * x, byte_count * x * y) 

# copy data to get back to standard memory layout 
data = headdata.copy() 

Il codice sfrutta impostando l'attributo strides per riflettere la mappatura della memoria personalizzati e per creare la (si spera) corretto array multidimensionale. Successivamente, copia l'intero array in data, per tornare a un layout di memoria standard.

+0

Grazie per i collegamenti. Occasionalmente devo interfacciarmi con MATLAB/Octave, quindi sapere che fanno cose nel layout di Fortran è comodo! – Theolodus

0

Dai uno sguardo allo nibabel, una libreria python che implementa lettori/scrittori per il formato "Analizza". Potrebbe aver già risolto questo per te.

+0

Grazie per il suggerimento - la nibabel sembra piuttosto bella. Devo occuparmi di altri formati, quindi questa potrebbe essere la strada da percorrere ... – Theolodus

Problemi correlati