Commit a69fee9dc89a6dab5b4bf4a28b23d945e8182504

Authored by David Mayerich
1 parent 08ada8c2

added python script for 3D phantom creation for 2D images

Showing 2 changed files with 78 additions and 5 deletions   Show diff stats
python/phantom.py 0 → 100644
  1 +# -*- coding: utf-8 -*-
  2 +"""
  3 +Created on Thu May 18 15:56:20 2017
  4 +
  5 +@author: david
  6 +"""
  7 +
  8 +import numpy as np
  9 +import scipy as sp
  10 +import scipy.misc
  11 +import scipy.ndimage
  12 +import matplotlib.pyplot as plt
  13 +import os
  14 +
  15 +#calculate a 3D image from a 2D binary mask
  16 +def binary(infile, sigma=2):
  17 +
  18 + I = sp.misc.imread(infile).astype(np.bool)
  19 +
  20 + #if the image has more than one channel, just keep the first one
  21 + if(I.ndim == 3):
  22 + I = I[:, :, 0]
  23 +
  24 + L = []
  25 + while np.count_nonzero(I) != 0:
  26 + L.append(I)
  27 + I = sp.ndimage.binary_erosion(I)
  28 +
  29 + #create a 3D image representing the new stack
  30 + S = np.zeros( (I.shape[0], I.shape[1], len(L) * 2 - 1) )
  31 +
  32 + #for each image in the list
  33 + for i in range(0, len(L)):
  34 + if(i == 0):
  35 + S[:, :, len(L) - 1] = L[0]
  36 + else:
  37 + S[:, :, len(L) - 1 + i] = L[i]
  38 + S[:, :, len(L) - 1 - i] = L[i]
  39 +
  40 + S = sp.ndimage.filters.gaussian_filter(S, sigma)
  41 + return S
  42 +
  43 +#generate a 3D image stack from a 2D binary mask
  44 +def binary_stack(infile, outdir, sigma=2):
  45 + outfile_base = os.path.basename(infile)
  46 + outfile_prefix, outfile_ext = os.path.splitext(outfile_base)
  47 +
  48 + S = binary(infile, sigma)
  49 +
  50 + zcount = len(str(S.shape[2]))
  51 + for f in range(0, S.shape[2]):
  52 + fname = outdir + "/" + outfile_prefix + str(f).zfill(zcount) + outfile_ext
  53 +
  54 + sp.misc.imsave(fname, S[:, :, f])
  55 +
  56 +
  57 +
  58 +
... ...
python/structen.py
... ... @@ -17,9 +17,7 @@ def st2(I, s=1, dtype=np.float32):
17 17  
18 18 #calculate the gradient
19 19 dI = np.gradient(I.astype(dtype))
20   -
21   - #print(dI[1][20, 164])
22   -
  20 +
23 21 #calculate the dimensions of the tensor field
24 22 field_dims = [dI[0].shape[0], dI[0].shape[1], 3]
25 23  
... ... @@ -33,6 +31,10 @@ def st2(I, s=1, dtype=np.float32):
33 31 Tg[:, :, ti] = dI[j] * dI[i]
34 32 ti = ti + 1
35 33  
  34 + #if the user does not want a blurred field
  35 + if(s == 0):
  36 + return Tg
  37 +
36 38 #blur the tensor field
37 39 T = np.zeros(field_dims, dtype=dtype)
38 40  
... ... @@ -125,7 +127,7 @@ def sym2mat(T):
125 127  
126 128 return R
127 129  
128   -def st2vec(S, vector=0):
  130 +def vec(S, vector=0):
129 131  
130 132 if(S.ndim != 3):
131 133 print("ERROR: a 2D slice is expected")
... ... @@ -238,7 +240,20 @@ def fa(S):
238 240 FA = np.sqrt(3./2.) * np.sqrt(fa_num) / np.sqrt(fa_den)
239 241 return FA
240 242  
241   -def st2amira(filename, T):
  243 +#calculate the specified eigenvalue for the tensor field
  244 +def eigenval(S, ev):
  245 + Sf = sym2mat(S)
  246 +
  247 + #calculate the eigenvectors and eigenvalues
  248 + l, v = np.linalg.eig(Sf)
  249 +
  250 + #store the sorted eigenvalues
  251 + ls = np.sort(l)
  252 + evals = ls[:, :, ev]
  253 +
  254 + return evals
  255 +
  256 +def amira(filename, T):
242 257 #generates a tensor field that can be imported into Amira
243 258  
244 259 # 0 dx dx ----> 0
... ...