def Affine(I_src, I_tar, cfOb): '''Function for finding and applyiing the affine between two image fragments, I_src and I_tar. Returns both images with the affine applied and the affine trasform''' if cfOb.affine == 'None': landmarks = pp.LandmarkPicker( [np.squeeze(I_src.asnp()), np.squeeze(I_tar.asnp())]) #will be forward from BFI to SSI for lm in landmarks: lm[0] = np.ndarray.tolist( np.multiply(lm[0], I_src.spacing().tolist()[0:2]) + I_src.origin().tolist()[0:2]) lm[1] = np.ndarray.tolist( np.multiply(lm[1], I_tar.spacing().tolist()[0:2]) + I_tar.origin().tolist()[0:2]) aff = apps.SolveAffine(landmarks) cfOb.affine = aff.tolist() I_src_aff = I_tar.copy() I_tar_aff = I_src.copy() cc.ApplyAffineReal(I_src_aff, I_src, cfOb.affine) cc.ApplyAffineReal(I_tar_aff, I_tar, np.linalg.inv(np.array(cfOb.affine))) return I_src_aff, I_tar_aff, cfOb.affine
def main(): secNum = sys.argv[1] mkyNum = sys.argv[2] channel = sys.argv[3] region = str(sys.argv[4]) conf_dir = '/home/sci/blakez/korenbergNAS/3D_database/Working/Microscopic/confocal/src_registration/' side_dir = '/home/sci/blakez/korenbergNAS/3D_database/Working/Microscopic/side_light_microscope/src_registration/' save_dir = '/home/sci/blakez/korenbergNAS/3D_database/Working/Microscopic/confocal/sidelight_registered/' # DIC = '/home/sci/blakez/Reflect Affine/DIC_to_Reflect.txt' src_pt = conf_dir + 'M{0}/section_{1}/{2}/section_{1}_confocal_relation_with_sidelight.txt'.format(mkyNum, secNum, region) tar_pt = side_dir + 'M{0}/section_{1}/section_{1}_sidelight_relation_with_confocal.txt'.format(mkyNum, secNum) # SID = '/home/sci/blakez/Reflect Affine/sidelight_to_DIC.txt' src_im = common.LoadITKImage(conf_dir + 'M{0}/section_{1}/{3}/Ch{2}/M{0}_{1}_LGN_RHS_Ch{2}_z00.tif'.format(mkyNum, secNum, channel, region)) # tar_im = common.LoadITKImage('M{0}/{1}/Crop_ThirdNerve_EGFP_z16.tiff'.format(mkyNum, secNum)) # The points need to be chosen in the origin corrected sidescape for downstream purposes affine = load_and_solve(tar_pt, src_pt) out_grid = bb_grid_solver(src_im, affine) z_stack = [] num_slices = len(glob.glob(conf_dir + 'M{0}/section_{1}/{3}/Ch{2}/*'.format(mkyNum, secNum, channel, region))) for z in range(0, num_slices): src_im = common.LoadITKImage(conf_dir + 'M{0}/section_{1}/{4}/Ch{2}/M{0}_{1}_LGN_RHS_Ch{2}_z{3}.tif'.format(mkyNum, secNum, channel, str(z).zfill(2), region)) aff_im = ca.Image3D(out_grid, ca.MEM_HOST) cc.ApplyAffineReal(aff_im, src_im, affine) common.SaveITKImage(aff_im, save_dir + 'M{0}/section_{1}/{4}/Ch{2}/M{0}_01_section_{1}_LGN_RHS_Ch{2}_conf_aff_sidelight_z{3}.tiff'.format(mkyNum, secNum, channel, str(z).zfill(2), region)) z_stack.append(aff_im) print('==> Done with {0}/{1}'.format(z, num_slices - 1)) stacked = cc.Imlist_to_Im(z_stack) stacked.setSpacing(ca.Vec3Df(out_grid.spacing()[0], out_grid.spacing()[1], 0.03/num_slices)) common.SaveITKImage(stacked, save_dir + 'M{0}/section_{1}/{3}/Ch{2}/M{0}_01_section_{1}_Ch{2}_conf_aff_sidelight_stack.nrrd'.format(mkyNum, secNum, channel, region)) common.DebugHere() if channel==0: cc.WriteGrid(stacked.grid(), save_dir + 'M{0}/section_{1}/{2}/affine_registration_grid.txt'.format(mkyNum, secNum, region))
bfAff=[[float(v) for v in line.split()] for line in bfp] with open(outdir + 'mri_AFF_landmarks_index.txt', 'r') as mrp: mrAff=[[float(v) for v in line.split()] for line in mrp] AFF_landmarks = [[bfAff[x],mrAff[x]] for x in range(0,np.shape(mrAff)[0])] for lm in AFF_landmarks: lm[0] = np.ndarray.tolist(np.multiply(lm[0],BFIgrid.spacing().tolist()) + BFIgrid.origin().tolist()) lm[1] = np.ndarray.tolist(np.multiply(lm[1],MRIgrid.spacing().tolist()) + MRIgrid.origin().tolist()) print np.array(AFF_landmarks) Afw = apps.SolveAffine(AFF_landmarks) BFI_aff = MRI.copy() cc.ApplyAffineReal(BFI_aff, BFI, Afw) cd.Disp3Pane(BFI_aff) sys.exit() # Use the resulting affine transformed block to define landmarks for TPS with open(outdir + 'blockface_TPS_points_index.txt', 'r') as bfp: bfPoints=[[float(v) for v in line.split()] for line in bfp] with open(outdir + 'mri_TPS_points_index.txt', 'r') as mrp: mrPoints=[[float(v) for v in line.split()] for line in mrp] ### NOT THE RIGHT WAY TO COMBINE### TPS_landmarks = [[bfPoints[x],mrPoints[x]] for x in range(0,np.shape(mrPoints)[0])] for lm in TPS_landmarks: lm[0] = np.ndarray.tolist(np.multiply(lm[0],MRIgrid.spacing().tolist()) + MRIgrid.origin().tolist()) lm[1] = np.ndarray.tolist(np.multiply(lm[1],MRIgrid.spacing().tolist()) + MRIgrid.origin().tolist())
def RigidReg( Is, It, theta_step=.0001, t_step=.01, a_step=0, maxIter=350, plot=True, origin=None, theta=0, # only applies for 2D t=None, # only applies for 2D Ain=np.matrix(np.identity(3))): Idef = ca.Image3D(It.grid(), It.memType()) gradIdef = ca.Field3D(It.grid(), It.memType()) h = ca.Field3D(It.grid(), It.memType()) ca.SetToIdentity(h) x = ca.Image3D(It.grid(), It.memType()) y = ca.Image3D(It.grid(), It.memType()) DX = ca.Image3D(It.grid(), It.memType()) DY = ca.Image3D(It.grid(), It.memType()) diff = ca.Image3D(It.grid(), It.memType()) scratchI = ca.Image3D(It.grid(), It.memType()) ca.Copy(x, h, 0) ca.Copy(y, h, 1) if origin is None: origin = [(Is.grid().size().x + 1) / 2.0, (Is.grid().size().y + 1) / 2.0, (Is.grid().size().z + 1) / 2.0] x -= origin[0] y -= origin[1] numel = It.size().x * It.size().y * It.size().z immin, immax = ca.MinMax(It) imrng = max(immax - immin, .01) t_step /= numel * imrng theta_step /= numel * imrng a_step /= numel * imrng energy = [] a = 1 if cc.Is3D(Is): if theta: print "theta is not utilized in 3D registration" z = ca.Image3D(It.grid(), It.memType()) DZ = ca.Image3D(It.grid(), It.memType()) ca.Copy(z, h, 2) z -= origin[2] A = np.matrix(np.identity(4)) cc.ApplyAffineReal(Idef, Is, A) # cc.ApplyAffine(Idef, Is, A, origin) t = [0, 0, 0] for i in xrange(maxIter): ca.Sub(diff, Idef, It) ca.Gradient(gradIdef, Idef) ca.Copy(DX, gradIdef, 0) ca.Copy(DY, gradIdef, 1) ca.Copy(DZ, gradIdef, 2) # take gradient step for the translation ca.Mul(scratchI, DX, diff) t[0] += t_step * ca.Sum(scratchI) ca.Mul(scratchI, DY, diff) t[1] += t_step * ca.Sum(scratchI) ca.Mul(scratchI, DZ, diff) t[2] += t_step * ca.Sum(scratchI) A[0, 3] = t[0] A[1, 3] = t[1] A[2, 3] = t[2] if a_step > 0: DX *= x DY *= y DZ *= z DZ += DX DZ += DY DZ *= diff d_a = a_step * ca.Sum(DZ) a_prev = a a += d_a # multiplying by a/a_prev is equivalent to adding (a-aprev) A = A * np.matrix([[a / a_prev, 0, 0, 0], [ 0, a / a_prev, 0, 0 ], [0, 0, a / a_prev, 0], [0, 0, 0, 1]]) # Z rotation ca.Copy(DX, gradIdef, 0) ca.Copy(DY, gradIdef, 1) DX *= y ca.Neg_I(DX) DY *= x ca.Add(scratchI, DX, DY) scratchI *= diff theta = -theta_step * ca.Sum(scratchI) # % Recalculate A A = A * np.matrix( [[np.cos(theta), np.sin(theta), 0, 0], [-np.sin(theta), np.cos(theta), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) # Y rotation ca.Copy(DX, gradIdef, 0) ca.Copy(DZ, gradIdef, 2) DX *= z ca.Neg_I(DX) DZ *= x ca.Add(scratchI, DX, DZ) scratchI *= diff theta = -theta_step * ca.Sum(scratchI) # % Recalculate A A = A * np.matrix( [[np.cos(theta), 0, np.sin(theta), 0], [0, 1, 0, 0], [-np.sin(theta), 0, np.cos(theta), 0], [0, 0, 0, 1]]) # X rotation ca.Copy(DY, gradIdef, 1) ca.Copy(DZ, gradIdef, 2) DY *= z ca.Neg_I(DY) DZ *= y ca.Add(scratchI, DY, DZ) scratchI *= diff theta = -theta_step * ca.Sum(scratchI) # Recalculate A A = A * np.matrix( [[1, 0, 0, 0], [0, np.cos(theta), np.sin(theta), 0], [0, -np.sin(theta), np.cos(theta), 0], [0, 0, 0, 1]]) cc.ApplyAffineReal(Idef, Is, A) # cc.ApplyAffine(Idef, Is, A, origin) # % display Energy (and other figures) at the end energy.append(ca.Sum2(diff)) if (i == maxIter - 1) or (i > 75 and abs(energy[-1] - energy[-50]) < immax): cd.DispImage(diff, title='Difference Image', colorbar=True) plt.figure() plt.plot(energy) cd.DispImage(Idef, title='Deformed Image') break elif cc.Is2D(Is): # theta = 0 if t is None: t = [0, 0] # A = np.array([[a*np.cos(theta), np.sin(theta), t[0]], # [-np.sin(theta), a*np.cos(theta), t[1]], # [0, 0, 1]]) A = np.copy(Ain) cc.ApplyAffineReal(Idef, Is, A) # ca.Copy(Idef, Is) for i in xrange(1, maxIter): # [FX,FY] = gradient(Idef) ca.Sub(diff, Idef, It) ca.Gradient(gradIdef, Idef) ca.Copy(DX, gradIdef, 0) ca.Copy(DY, gradIdef, 1) # take gradient step for the translation ca.Mul(scratchI, DX, diff) t[0] += t_step * ca.Sum(scratchI) ca.Mul(scratchI, DY, diff) t[1] += t_step * ca.Sum(scratchI) # take gradient step for the rotation theta if a_step > 0: # d/da DX *= x DY *= y DY += DX DY *= diff d_a = a_step * ca.Sum(DY) a += d_a # d/dtheta ca.Copy(DX, gradIdef, 0) ca.Copy(DY, gradIdef, 1) DX *= y ca.Neg_I(DX) DY *= x ca.Add(scratchI, DX, DY) scratchI *= diff d_theta = theta_step * ca.Sum(scratchI) theta -= d_theta # Recalculate A, Idef A = np.matrix([[a * np.cos(theta), np.sin(theta), t[0]], [-np.sin(theta), a * np.cos(theta), t[1]], [0, 0, 1]]) A = Ain * A cc.ApplyAffineReal(Idef, Is, A) # cc.ApplyAffine(Idef, Is, A, origin) # % display Energy (and other figures) at the end energy.append(ca.Sum2(diff)) if (i == maxIter - 1) or (i > 75 and abs(energy[-1] - energy[-50]) < immax): if i == maxIter - 1: print "not converged in ", maxIter, " Iterations" if plot: cd.DispImage(diff, title='Difference Image', colorbar=True) plt.figure() plt.plot(energy) cd.DispImage(Idef, title='Deformed Image') break return A
cc.CreateRect(square, [0, 0], [440, 440]) BFI_VE *= square cc.VarianceEqualize_I(BFI_VE, sigma=5.0) cc.VarianceEqualize_I(MRI_VE, sigma=5.0) grid_orig = BFI_VE.grid().copy() grid_new = cc.MakeGrid(grid_orig.size(), [1, 1, 1], 'center') BFI_VE.setGrid(grid_new) MRI_VE.setGrid(grid_new) BFI_VE_def = ca.Image3D(grid_new, BFI_VE.memType()) # do rigid reg first # A = AffineReg(BFI_VE, MRI_VE, constraint='rigid', plot=debug) A = AffineReg(BFI_VE, MRI_VE, plot=debug, maxIter=400, verbose=0)[1] cc.ApplyAffineReal(BFI_VE_def, BFI_VE, A) # cd.DispImage(BFI_VE_def) # cd.DispImage(MRI_VE) # hA = ca.Field3D(BFI_VE.grid(), BFI_VE.memType()) # cc.AtoH(hA, A) # cd.DispHGrid(hA, splat=False) # sys.exit() if block == 1: nIters = 100 sigma = .03 step = .00002 elif block == 2: nIters = 100 sigma = .003 step = .00002
# [[ 73.0, 92.0, 97.0] , [60.0, 82.0, 77.0]], # TEST # [[ 124.0, 66.0, 66.0] , [147.0,34.0,127.0]], # [[ 100.0, 66.0, 66.0] , [119.0,32.0,128.0]], # [[ 110.0, 35.0, 121.0] , [125.0,135.0,168.0]], # [[ 111.0, 60.0, 97.0] , [128.0,87.0,135.0]]] #good # with open(SaveDir + 'T2_registered/M13_01_Live-T2_Landmarks.json', 'w') as f: # json.dump(landmarks, f) realLM = np.array(landmarks) realLM[:, 0] = realLM[:, 0] * live.spacing() + live.origin() realLM[:, 1] = realLM[:, 1] * T2.spacing() + T2.origin() A = apps.SolveAffine(realLM) liveDef = T2.copy() cc.ApplyAffineReal(liveDef, live, A) # # Convert the landmarks to real coordinates and exchange the ordering of the so live is going to T2 # realLM[:,1] = realLM[:,1] - 127.5 # flipLM = np.fliplr(realLM) # # Solve for the TPS based off of the landmakrs # spline = SolveSpline(flipLM) # h = SplineToHField(spline, T2Grid, memT) # print ca.MinMax(h) # liveDef = T2.copy() # cc.ApplyHReal(liveDef,live,h) # Variance equalize the volumes and blur the live T2_VE = ca.Image3D(T2.grid(), memT)
def main(): # Extract the Monkey number and section number from the command line global frgNum global secOb mkyNum = sys.argv[1] secNum = sys.argv[2] frgNum = int(sys.argv[3]) write = True # if not os.path.exists(os.path.expanduser('~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml'.format(mkyNum,secNum))): # cf = initial(secNum, mkyNum) try: secOb = Config.Load( secSpec, pth.expanduser( '~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml' .format(mkyNum, secNum))) except IOError as e: try: temp = Config.LoadYAMLDict(pth.expanduser( '~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml' .format(mkyNum, secNum)), include=False) secOb = Config.MkConfig(temp, secSpec) except IOError: print 'It appears there is no configuration file for this section. Please initialize one and restart.' sys.exit() if frgNum == int(secOb.yamlList[frgNum][-6]): Fragmenter() try: secOb = Config.Load( secSpec, pth.expanduser( '~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml' .format(mkyNum, secNum))) except IOError: print 'It appeas that the include yaml file list does not match your fragmentation number. Please check them and restart.' sys.exit() if not pth.exists( pth.expanduser(secOb.ssiOutPath + 'frag{0}'.format(frgNum))): common.Mkdir_p( pth.expanduser(secOb.ssiOutPath + 'frag{0}'.format(frgNum))) if not pth.exists( pth.expanduser(secOb.bfiOutPath + 'frag{0}'.format(frgNum))): common.Mkdir_p( pth.expanduser(secOb.bfiOutPath + 'frag{0}'.format(frgNum))) if not pth.exists( pth.expanduser(secOb.ssiSrcPath + 'frag{0}'.format(frgNum))): os.mkdir(pth.expanduser(secOb.ssiSrcPath + 'frag{0}'.format(frgNum))) if not pth.exists( pth.expanduser(secOb.bfiSrcPath + 'frag{0}'.format(frgNum))): os.mkdir(pth.expanduser(secOb.bfiSrcPath + 'frag{0}'.format(frgNum))) frgOb = Config.MkConfig(secOb.yamlList[frgNum], frgSpec) ssiSrc, bfiSrc, ssiMsk, bfiMsk = Loader(frgOb, ca.MEM_HOST) #Extract the saturation Image from the color iamge bfiHsv = common.FieldFromNPArr( matplotlib.colors.rgb_to_hsv( np.rollaxis(np.array(np.squeeze(bfiSrc.asnp())), 0, 3)), ca.MEM_HOST) bfiHsv.setGrid(bfiSrc.grid()) bfiSat = ca.Image3D(bfiSrc.grid(), bfiHsv.memType()) ca.Copy(bfiSat, bfiHsv, 1) #Histogram equalize, normalize and mask the blockface saturation image bfiSat = cb.HistogramEqualize(bfiSat, 256) bfiSat.setGrid(bfiSrc.grid()) bfiSat *= -1 bfiSat -= ca.Min(bfiSat) bfiSat /= ca.Max(bfiSat) bfiSat *= bfiMsk bfiSat.setGrid(bfiSrc.grid()) #Write out the blockface region after adjusting the colors with a format that supports header information if write: common.SaveITKImage( bfiSat, pth.expanduser(secOb.bfiSrcPath + 'frag{0}/M{1}_01_bfi_section_{2}_frag{0}_sat.nrrd'. format(frgNum, secOb.mkyNum, secOb.secNum))) #Set the sidescape grid relative to that of the blockface ssiSrc.setGrid(ConvertGrid(ssiSrc.grid(), bfiSat.grid())) ssiMsk.setGrid(ConvertGrid(ssiMsk.grid(), bfiSat.grid())) ssiSrc *= ssiMsk #Write out the sidescape masked image in a format that stores the header information if write: common.SaveITKImage( ssiSrc, pth.expanduser(secOb.ssiSrcPath + 'frag{0}/M{1}_01_ssi_section_{2}_frag{0}.nrrd'. format(frgNum, secOb.mkyNum, secOb.secNum))) #Update the image parameters of the sidescape image for future use frgOb.imSize = ssiSrc.size().tolist() frgOb.imOrig = ssiSrc.origin().tolist() frgOb.imSpac = ssiSrc.spacing().tolist() updateFragOb(frgOb) #Find the affine transform between the two fragments bfiAff, ssiAff, aff = Affine(bfiSat, ssiSrc, frgOb) updateFragOb(frgOb) #Write out the affine transformed images in a format that stores header information if write: common.SaveITKImage( bfiAff, pth.expanduser( secOb.bfiOutPath + 'frag{0}/M{1}_01_bfi_section_{2}_frag{0}_aff_ssi.nrrd'.format( frgNum, secOb.mkyNum, secOb.secNum))) common.SaveITKImage( ssiAff, pth.expanduser( secOb.ssiOutPath + 'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_aff_bfi.nrrd'.format( frgNum, secOb.mkyNum, secOb.secNum))) bfiVe = bfiAff.copy() ssiVe = ssiSrc.copy() cc.VarianceEqualize_I(bfiVe, sigma=frgOb.sigVarBfi, eps=frgOb.epsVar) cc.VarianceEqualize_I(ssiVe, sigma=frgOb.sigVarSsi, eps=frgOb.epsVar) #As of right now, the largest pre-computed FFT table is 2048, so resample onto that grid for registration regGrd = ConvertGrid( cc.MakeGrid(ca.Vec3Di(2048, 2048, 1), ca.Vec3Df(1, 1, 1), ca.Vec3Df(0, 0, 0)), ssiSrc.grid()) ssiReg = ca.Image3D(regGrd, ca.MEM_HOST) bfiReg = ca.Image3D(regGrd, ca.MEM_HOST) cc.ResampleWorld(ssiReg, ssiVe) cc.ResampleWorld(bfiReg, bfiVe) #Create the default configuration object for IDiff Matching and then set some parameters idCf = Config.SpecToConfig(IDiff.Matching.MatchingConfigSpec) idCf.compute.useCUDA = True idCf.io.outputPrefix = '/home/sci/blakez/IDtest/' #Run the registration ssiDef, phi = DefReg(ssiReg, bfiReg, frgOb, ca.MEM_DEVICE, idCf) #Turn the deformation into a displacement field so it can be applied to the large tif with C++ code affV = phi.copy() cc.ApplyAffineReal(affV, phi, np.linalg.inv(frgOb.affine)) ca.HtoV_I(affV) #Apply the found deformation to the input ssi ssiSrc.toType(ca.MEM_DEVICE) cc.HtoReal(phi) affPhi = phi.copy() ssiBfi = ssiSrc.copy() upPhi = ca.Field3D(ssiSrc.grid(), phi.memType()) cc.ApplyAffineReal(affPhi, phi, np.linalg.inv(frgOb.affine)) cc.ResampleWorld(upPhi, affPhi, bg=2) cc.ApplyHReal(ssiBfi, ssiSrc, upPhi) # ssiPhi = ca.Image3D(ssiSrc.grid(), phi.memType()) # upPhi = ca.Field3D(ssiSrc.grid(), phi.memType()) # cc.ResampleWorld(upPhi, phi, bg=2) # cc.ApplyHReal(ssiPhi, ssiSrc, upPhi) # ssiBfi = ssiSrc.copy() # cc.ApplyAffineReal(ssiBfi, ssiPhi, np.linalg.inv(frgOb.affine)) # #Apply affine to the deformation # affPhi = phi.copy() # cc.ApplyAffineReal(affPhi, phi, np.linalg.inv(frgOb.affine)) if write: common.SaveITKImage( ssiBfi, pth.expanduser( secOb.ssiOutPath + 'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_def_bfi.nrrd'.format( frgNum, secOb.mkyNum, secOb.secNum))) cc.WriteMHA( affPhi, pth.expanduser( secOb.ssiOutPath + 'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_to_bfi_real.mha'. format(frgNum, secOb.mkyNum, secOb.secNum))) cc.WriteMHA( affV, pth.expanduser( secOb.ssiOutPath + 'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_to_bfi_disp.mha'. format(frgNum, secOb.mkyNum, secOb.secNum))) #Create the list of names that the deformation should be applied to # nameList = ['M15_01_0956_SideLight_DimLED_10x_ORG.tif', # 'M15_01_0956_TyrosineHydroxylase_Ben_10x_Stitching_c1_ORG.tif', # 'M15_01_0956_TyrosineHydroxylase_Ben_10x_Stitching_c2_ORG.tif', # 'M15_01_0956_TyrosineHydroxylase_Ben_10x_Stitching_c3_ORG.tif'] # appLarge(nameList, affPhi) common.DebugHere()
M15.spacing().tolist()) + M15.origin().tolist()) #Solve for the affine, inverse is M15 to M13, forward is M13 to M15 aff = apps.SolveAffine(landmarks) with open(M13dir + 'TPS/M13_01_TPSLandmarks_5.txt', 'r') as m13: TPS13 = [[float(v) for v in line.split()] for line in m13] with open(M15dir + 'TPS/M15_01_TPSLandmarks_5.txt', 'r') as m15: TPS15 = [[float(v) for v in line.split()] for line in m15] if M15_to_M13: write = True def_aff = ca.Image3D(M13_aff.grid(), memT) cc.ApplyAffineReal(def_aff, M15, np.linalg.inv(aff)) if write: cc.WriteMHA(def_aff, M15dir + 'Affine/M15_01_MRI_affine_to_M13.mha') np.save(M15dir + 'Affine/M15_01_MRI_affMat_to_M13.npy', np.linalg.inv(aff)) landmarks = [[TPS13[x], TPS15[x]] for x in range(0, np.shape(TPS15)[0])] # Convert to real coordinates for lm in landmarks: lm[0] = np.ndarray.tolist( np.multiply(lm[0], M13_aff.spacing().tolist()) + M13_aff.origin().tolist()) lm[1] = np.ndarray.tolist(