In [1]:
import sys
sys.path.insert(0, '../../../ndreg/')
sys.path.insert(0,'../code/functions/')
import ndreg
import math
import cv2
import pickle
import numpy as np
import SimpleITK as itk
import matplotlib.pyplot as plt
import plosLib as pLib
import connectLib as cLib
import connectLib as cLib
from affine import Affine
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
from random import randrange as rand
from random import uniform as floatRand
from PIL import Image
In [19]:
def register(inImg, baseImg, iterations, MI=False):
return ndreg.imgAffineComposite(inImg,
baseImg,
iterations=iterations,
useMI=MI,
verbose=False)
In [3]:
def getTransform(pitchRange = .1,
rollRange = .1,
yawRange = .1,
xRange = 0.,
yRange = 0.,
zRange = 0.,
pitch=None,
yaw=None,
roll=None,
zT=None,
yT=None,
xT=None):
#generate a random rigid body transform in given bounds
a = floatRand(pitchRange-(pitchRange/2.), pitchRange+(pitchRange/2.))
b = floatRand(yawRange-(yawRange/2.), yawRange+(yawRange/2.))
c = floatRand(rollRange-(rollRange/2.), rollRange+(rollRange/2.))
xt = floatRand(xRange-(xRange/2.), xRange+(xRange/2.))
yt = floatRand(yRange-(yRange/2.), yRange+(yRange/2.))
zt = floatRand(zRange-(zRange/2.), zRange+(zRange/2.))
#set default params, if passed
if yaw is not None:
a = yaw
if pitch is not None:
b = pitch
if roll is not None:
c = roll
if xT is not None:
xt = xT
if yT is not None:
yt = yT
if zT is not None:
zt = zT
#generate the transform
transform = np.stack([
[math.cos(a)*math.cos(b), math.cos(a)*math.sin(b)*math.sin(c)-math.sin(a)*math.cos(c), math.cos(a)*math.sin(b)*math.cos(c)+math.sin(a)*math.sin(c), xt],
[math.sin(a)*math.cos(b), math.sin(a)*math.sin(b)*math.sin(c)+math.cos(a)*math.cos(c), math.sin(a)*math.sin(b)*math.cos(c)-math.cos(a)*math.sin(c), yt],
[-math.sin(b), math.cos(b)*math.sin(c), math.cos(b)*math.cos(c), zt],
[0., 0., 0., 1.]
])
return transform
def applyRigid(initialVolume, transform, verbose=False):
#create a body to hold return values
rigidMatrix = np.zeros_like(initialVolume)
#create vars to keep track of out of bounds percent
out = 0.
#convert every voxel
for z in range(initialVolume.shape[0]):
for y in range(initialVolume.shape[1]):
for x in range(initialVolume.shape[2]):
#shift the volume so that the transform is applied to the center, and not the top left back edge
shift = [initialVolume.shape[2]/2., initialVolume.shape[1]/2., initialVolume.shape[0]/2.]
shiftedPoint = list(np.subtract([x, y, z], shift))
shiftedPoint.append(1.)
#calculate the transform, drop the irrelavent 1 at the end
new = np.dot(transform, shiftedPoint)[:3]
#shift the volume back to its original spot after transform
final = np.add(new, shift)
#attempt to assign new spot
try:
rigidMatrix[int(final[2]), int(final[1]), int(final[0])] = initialVolume[z, y, x]
#if transformed place is out of bounds, dont assign it
except IndexError:
out+=1.
continue
#print information, if required
if verbose:
print 'Out of bounds fraction: ', out/float(initialVolume.shape[0]*initialVolume.shape[1]*initialVolume.shape[2])
return rigidMatrix
In [4]:
realData = pickle.load(open('../code/tests/synthDat/realDataRaw_t0.synth', 'r'))
print realData.shape
In [5]:
testData = realData[:7]
print testData.shape
In [10]:
def executeTest(testImg, baseImg, gradientIterations = 200, verbose=True):
initialErr = np.sum((np.subtract(baseImg, testImg))**2)
testImgITK = itk.GetImageFromArray(testImg)
testImgITK.SetSpacing([.12, .12, .5])
baseImgITK = itk.GetImageFromArray(baseImg)
baseImgITK.SetSpacing([.12, .12, .5])
if verbose:
print '\tInitial Error: ', initialErr
transform = register(testImgITK, baseImgITK, gradientIterations)
if verbose:
print '\tTransform:'
print transform
regImg = itk.GetArrayFromImage(
ndreg.imgApplyAffine(
testImgITK,
transform,
size=testImgITK.GetSize(),
spacing=testImgITK.GetSpacing()
)
)
finalErr = np.sum((np.subtract(baseImg, regImg))**2)
errReductionRatio = np.subtract(initialErr, finalErr)/float(initialErr)
if verbose:
print '\tFinal Error: ', finalErr
print '\tError Reduction Ratio: ', errReductionRatio
return regImg, initialErr, finalErr, errReductionRatio
In [7]:
outVolume = cLib.otsuVox(pLib.pipeline(testData))
In [8]:
#As expected, slices 0 and 6 are ill defined, so remove them
outVolume = outVolume[1:6]
print outVolume.shape
In [9]:
#generate and apply a basic transform to the output
transform = getTransform(pitch=0., yaw=.15, roll=0., xT=0., yT=0., zT=0.)
transformVolume = applyRigid(outVolume, transform, True)
In [20]:
#Check if NDReg handles the basic case
regImg, initialErr, finalErr, reductionRatio = executeTest(transformVolume, outVolume, 200, verbose=True)
In [21]:
def executeTest(testImg, baseImg, gradientIterations = 200, verbose=True):
initialErr = np.sum((np.subtract(baseImg, testImg))**2)
testImgITK = itk.GetImageFromArray(testImg)
baseImgITK = itk.GetImageFromArray(baseImg)
if verbose:
print '\tInitial Error: ', initialErr
transform = register(testImgITK, baseImgITK, gradientIterations)
if verbose:
print '\tTransform:'
print transform
regImg = itk.GetArrayFromImage(
ndreg.imgApplyAffine(
testImgITK,
transform,
size=testImgITK.GetSize(),
spacing=testImgITK.GetSpacing()
)
)
finalErr = np.sum((np.subtract(baseImg, regImg))**2)
errReductionRatio = np.subtract(initialErr, finalErr)/float(initialErr)
if verbose:
print '\tFinal Error: ', finalErr
print '\tError Reduction Ratio: ', errReductionRatio
return regImg, initialErr, finalErr, errReductionRatio
In [22]:
def register(inImg, baseImg, iterations, MI=False):
return ndreg.imgAffine(inImg,
baseImg,
iterations=iterations,
useMI=MI,
verbose=False)
In [23]:
regImg, initialErr, finalErr, reductionRatio = executeTest(transformVolume, outVolume, 200, verbose=True)
In [ ]: